当前位置: 首页 > news >正文

JAR 包冲突排雷指南:原理、现象与 Maven 一站式解决

一次诡异的 NoSuchMethodError,90 % 都是由同一个类在多个版本间反复横跳引起的。

一、为什么会冲突?

1.1 冲突产生的根因:同一个类在 classpath 中出现多次,且版本不同

以开篇例子为例:

  • a.jar → 引入 c.jar(version-1)
  • b.jar → 引入 c.jar(version-2)

项目运行时 “先到先得” 的类加载顺序导致:

加载顺序结果
先加载 c-1低版本类 ClassA 缺失 methodA()NoSuchMethodError
先加载 c-2高版本向下兼容,一切正常

1.2 典型异常对照表

异常含义
java.lang.ClassNotFoundException版本里根本没有这个类
java.lang.NoSuchMethodError版本里有类,但没有这个方法
java.lang.NoSuchFieldError版本里有类,但没有这个字段
java.lang.LinkageError类加载冲突导致链接失败

二、排查思路:三步定位法

Step 1:打印依赖树 —— 用 Maven 做“CT 扫描”

mvn dependency:tree -Dverbose -Dincludes=:notify-common

输出示例(已高亮冲突):

[INFO] +- com.taobao.wlb:bis-core:jar:1.0-SNAPSHOT
[INFO] |  \- com.taobao.logistics:schedule-client:1.1.1
[INFO] |     \- (com.taobao.notify:notify-common:1.8.15 - omitted for conflict with 1.8.19.26)
[INFO] \- com.taobao.notify:notify-tr-client:1.8.19.26
[INFO]    \- com.taobao.notify:notify-common:1.8.19.26
  • 冲突版本1.8.15 vs 1.8.19.26
  • 谁是引入者schedule-client:1.1.1 拉来了旧版本。

Step 2:运行时类加载详情 —— JVM 的“X 光片”

启动参数加 -verbose:class,查看实际从哪个 JAR 加载:

[Loaded com.xxx.ClassA from file:/.../c-1.0.jar]

Step 3:IDE 可视化 —— 适合“肉眼”快速定位

  • Eclipse:打开 pom.xml → Hierarchy → 搜索冲突包
  • IDEApom.xml → Diagrams → Show Dependencies

三、解决手段:让“对的版本”留下来

3.1 排除旧版本(Maven)

找到引入冲突的坐标,在 pom.xml 中显式排除:

<dependency><groupId>com.know.diamond</groupId><artifactId>diamond-sdk</artifactId><version>2.0.5</version><exclusions><exclusion><groupId>com.google.collections</groupId><artifactId>google-collections</artifactId></exclusion></exclusions>
</dependency>

3.2 统一版本:使用 dependencyManagement

<dependencyManagement><dependencies><dependency><groupId>com.taobao.notify</groupId><artifactId>notify-common</artifactId><version>1.8.19.26</version></dependency></dependencies>
</dependencyManagement>

3.3 全局分析:一次性导出完整树

mvn dependency:tree -Dverbose > tree.log

用文本编辑器搜索冲突 groupId:artifactId,快速定位所有叶子节点。


四、小结:一张图看懂排包流程

┌────────────┐      ┌──────────────┐      ┌────────────────┐
│ NoSuchM··· │  →   │ dependency:  │  →   │ exclusion /    │
│ LinkageErr │      │ tree -Dverbose│      │ dependencyMgmt │
└────────────┘      └──────────────┘      └────────────────┘↑                   ↑                     ↑运行报错           快速定位冲突            精准解决

一句话记住:先 tree 找元凶,再 exclusion 干掉它,最后用 dependencyManagement 统一版本,冲突永不再现!

http://www.dtcms.com/a/279688.html

相关文章:

  • 深度解读virtio:Linux IO虚拟化核心机制
  • 评论设计开发
  • RedisJSON 技术揭秘`JSON.DEBUG MEMORY` 量化 JSON 键的内存占用
  • Python深浅拷贝全解析:从原理到实战的避坑指南
  • 深度解析:htmlspecialchars 与 nl2br 结合使用的前后端协作之道,大学毕业论文——仙盟创梦IDE
  • 工业场合需要千变万化的模拟信号,如何获取?
  • B4016 树的直径
  • 阿尔卡特ASM180TD181TD氦检漏器ALCATEL
  • 使用dify生成测试用例
  • 【第一章编辑器开发基础第二节编辑器布局_3间距控制(4/4)】
  • OpenCV C++ 中的掩码(Mask)操作
  • 微服务初步入门
  • 设计模式之适配器模式:让不兼容的接口协同工作的艺术
  • Unreal5从入门到精通之如何实现UDP Socket通讯
  • 【C++进阶】---- 多态
  • 解锁文档处理新体验:Python库Agentic Document Extraction
  • OneCode3.0 通信架构简介——MCPServer微内核设计哲学与实现
  • Web学习笔记4
  • 算法训练营day16 513.找树左下角的值、112. 路径总和、106.从中序与后序遍历序列构造二叉树
  • 探索 Sort.h:多功能排序算法模板库
  • [element-ui]el-table在可视区域底部固定一个横向滚动条
  • 智源全面开源RoboBrain 2.0与RoboOS 2.0:刷新10项评测基准,多机协作加速群体智能
  • MCP 第三波升级!Function Call 多步调用 + 流式输出详解
  • QWidget 和 QML 的本质和使用上的区别
  • 慢查询日志监控:定位性能瓶颈的第一步
  • 【抖音滑动验证码风控分析】
  • 小架构step系列14:白盒集成测试原理
  • C# TCP粘包与拆包深度了解
  • spark广播表大小超过Spark默认的8GB限制
  • FatJar打包和FatJar启动配置文件修改。