我们的大部分工作都是在维护老的应用或者在老应用上做开发,而在开发以及架构升级的的过程中,会不可避免的引入一些新的maven包。由于间接依赖冲突导致的应用启动失败情况屡见不鲜,问题的关键,就是找到关键的问题。那么如何更好的定位maven包的冲突点呢?
1. 排包方法
maven默认的包加载顺序;
第一原则:路径最短优先。
路径1:A->B->C->D(version1.0)
路径2:F->E->D(version2.0)
由于路径2的长度小于路径1,所以结果就是A会传递性依赖D(version2.0)
第二原则:先声明优先。
当路径长度相等的时候,使用第二原则: 路径1:A->B->C(version1.0)
路径2:D->E->C(version2.0)
由于路径1在路径2前面声明,所以结果就是D会传递性依赖C(version1.0)
排包方式:
一般情况下,我们是直接在根pom.xml文件中标签下进行排包,这样,整个应用的所有模块都会统一排包:
xml
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<exclusions>
<exclusion>
<groupId>xxx</groupId>
<artifactId>xx</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</dependencyManagement>
2. 从启动日志入手
启动日志中一般会有报错信息:
找到报错信息最根上的caused by,之后在应用中全局搜索导致问题发生的类名,之后定位到类在哪个依赖包,这时我们往往会发现,应用中有两个同名不同版本的依赖包,将其从我们新引入的依赖中排除。
在这过程中,我们往往还需要借助如下的命令打印依赖树:
mvn dependency:tree
3. 借助IDE工具
安装插件:MavenHelper
一些时候,尤其是在进行架构升级时,仅通过启动日志直接定位冲突点对于经验不丰富的新手是很困难的,这时我们可以采用一个更简单粗暴的方法,借助IDE工具直接定位二方包会冲突的依赖:
再筛选冲突包是,可以勾选上如下选项:
该工具可以显示出二方包下所有的间接依赖,之后我们可以排查哪个依赖与应用中已有的依赖有冲突。
最后,我们可以用最简单粗暴的方法,把冲突的包全都排掉~~
⚠️注意事项:
一些二方包可能自己和自己冲突,如果项目的其他位置并没有引入同名包的话,这种包是不能排除的(也不用排除):