详细带你了解 Maven 依赖冲突的问题原因,以及解决办法。并教你生产碰到这类的问题实战技巧。
依赖冲突是日常开发中经常碰到的过程,如果运气好,并不会有什么问题。偏偏小黑哥有点背,碰到好几次生产问题,排查一整晚,最后发现却是依赖冲突的引起的问题。
没碰到过这个问题同学可能没什么感觉,小黑哥举两个最近碰到例子,让大家感受一些。
例子 1:
我们公司有个古老的业务基础包 A。B,C 业务依赖这个包。某个团队拷贝 A 的部分代码进行重构,类名与路径完全一样,然后重新打包成 D 发布。
一次业务改动,B 业务也引入了 D 包,测试环境运行的时候,一切 OK,但是在生产运行时,却抛出 NoSuchMethodError
。
问题原因在于 B 业务依赖 A,D。而 A,D 存在两个同包同名类,运行的时候,具体加载谁,不同环境还真不一样。
例子 2:
A 业务使用 Dubbo
进行 RPC
调用, Dubbo
需要依赖 javassist
。当前依赖关系为:
A------->Dubbo------->javassist-3.18.1.GA
某次改动中引入另外一个第三方开源包,其依赖 javassist-3.15.0-GA
。生产发布的时候,将 javassist-3.15.0-GA
打包到应用中,由于生产环节为 JDK1.8,从而导致运行直接失败。
除了上述问题,依赖冲突还可能导致应用抛出 ClassNotFoundException
,NoClassDefFoundError
等错误。
抛出错误这种情况还算好,还比较容易定位问题。怕就怕,不同版本同一个类内部逻辑不同,从而导致业务异常。这种问题,真的很让人抓狂,让人头秃。
仔细分析依赖冲突,主要可以分为两类:
- 项目同一依赖应用,存在多版本,每个版本同一个类,可能存在差异。
- 项目不同依赖应用,存在包名,类名完全一样的类。
下面我们分析一下依赖冲突产生的原因。
0x01. 依赖冲突原因 1.1 依赖机制Maven
依赖分为两种情况,直接依赖与间接依赖,这个比较好理解