在我们引入新的jar包时候可能会因为传递依赖,引入现有项目中存在,但是版本不同的jar,从而引起jar包冲突,在有些情况下,运行并不会出现问题,其中的原因是:gradle有一套策略,在构建时候为我们进行了选择,实际线上部署的项目中只有一个版本的jar。 有时候,会导致单元测试不能运行,因此,我们需要找到冲突的jar,并对陈旧的版本进行升级,或者对传递依赖进行排除;
其中排除依赖的方式maven和gradle不同,这里讨论gradle管理的情况;
但是都可以使用exclude
dependencies { compile("com.aaa:web:1.0") { exclude group: 'org.unwanted', module: 'iAmBuggy' } }
这里再梳理一下如何发现冲突的jar,及其版本,解决思路
1.首先会发现 NoClassDef 、NoSuchMethod 等异常,根据堆栈信息, 在项目中找寻这个类。(IDEA 双击shift)。一般会发现两个类。这时候, 其实你已经可以看到两个jar的版本了。
2. 然后,使用
gradlew webapp-module-name:dependencies
gradlew dependencyInsight --dependency slf4j-api
命令,打印依赖树; 分析依赖关系,找到不同版本的依赖方。
3. 知道了是哪些内容,引入了不同jar,接着就是解决他们。主要的思路是,
A, 升级陈旧版本, 对于一些不冲突不引起异常的升级这里是提倡的,但是也要细细阅读相关使用的业务代码和jar源码,确保无误后; 提请测试,进行回归和压力测试。
B,消除传递依赖, 强制使用某个统一的依赖版本等,不是消除他们而是规避
,
领会:
1. 传递依赖的jar 不会打到这个A jar中形成jar中jar,项目所有直接间接依赖的jar都会放在同级目录下, 会放在最外层的公共依赖jar中
2. gradle 有一套选择重复jar 的机制,保证在形成的可执行war包中,只有同一个jar包的一个版本;关于选择策略可以参照:
https://www.cnblogs.com/gzdaijie/p/5296624.html