Maven检测解决jar包冲突

在项目开发中,多少都会遇到Maven的jar包冲突问题,如:

  • 引入新包后报了NoSuchMethodError
  • 很多个依赖都引入了不同版本的jar包A ,造成A的版本不统一。

要解决jar包冲突的问题,就需要先搞清楚Maven中的依赖传递原则 以及造成jar包冲突背后的原理

Maven中的依赖传递原则

Maven中的依赖传递原则为:最短路径优先原则,最先声明优先原则。

1. 最短路径优先原则

举例:假设工程引入了jar包AB ,它们都依赖了Z这个jar包:

A --> X --> Y --> Z(2.5)

B --> X --> Z(2.0)

则最终Z(2.0) 版本生效,因为它的路径更短。

2. 最先声明优先原则

举例:假设工程引入了jar包AB ,它们都依赖了Z这个jar包,在工程pom.xml文件中,A先于B声明:

A --> Z(2.5)

B --> Z(2.0)

则最终Z(2.5) 版本生效,因为这里A最先声明,所以传递过来的Z选用2.5版本。

Maven中Jar包冲突原理

根据上面的举例,假设工程中引入了jar包AB ,它们都依赖了Z这个jar包:

A --> X --> Y --> Z(2.5)

B --> X --> Z(2.0)

根据最短路径优先原则,最终依赖的是Z(2.0) 版本生效。

如果在Y 包中使用了Z包2.5版本中新的method ,当运行到这段逻辑时,就会报NoSuchMethodError

原因是: Y 包本来依赖Z的2.5版本,但因为jar包冲突,Maven根据最短路径优先原则选择了Z的2.0版本 ,而Z的2.0版本中没有这个新的method,导致出错。

注意: 不是所有冲突都会引起运行异常,只有高版本jar包向下不兼容,或者新增了某些低版本没有的API,则有可能导致冲突出错。

Maven冲突检测

1. 在IDEA安装Maven Helper插件

2. 使用Maven Helper插件进行jar包冲突检测

1)通过全部依赖树或列表,标亮的即存在jar包冲突,选中则可以查看jar包冲突具体版本

上图示例,表明log4j 这个jar包,有2个传递依赖,分别为1.2.14版本1.2.16版本,冲突描述为:

omitted for conflict with 1.2.14. --- 由于与1.2.14版本冲突而被省略

2)搜索jar包检测冲突

3)通过mvn命令检测冲突

命令为:mvn dependency:tree -Dverbose

注意:不要省略-Dverbose参数,否则不会显示被忽略的包

解决冲突

1. 排除法

选中冲突的jar包,点击右键,选择Exclude,即可排查掉此jar包

2. 版本锁定法

如果很多个依赖都传递了jar包A ,涉及了很多个版本,但只想指定一个版本,用排除法一个个去exclude太麻烦。

版本锁定法: 公司项目一般都会有父级pom文件,想指定哪个版本,只需在项目的父级pom中定义即可,其他子module的pom中,只引入依赖,不需要指定版本。

举例:

在项目父级pom中定义要依赖的mapstruct版本,如下:

xml 复制代码
<!-- 父级pom文件 -->
<dependencyManagement>
    <dependencies>
        <dependency>  
            <groupId>org.mapstruct</groupId>  
            <artifactId>mapstruct</artifactId>  
            <version>1.3.0.Final</version>  
        </dependency>
    </dependencies>
</dependencyManagement>

在其他子module的pom中,只引入依赖,不需要再指定mapstruct的版本,如下:

xml 复制代码
<!-- 子module的pom文件 -->
<dependencies>
    <dependency>  
        <groupId>org.mapstruct</groupId>  
        <artifactId>mapstruct</artifactId>  
    </dependency>
</dependencies>

注意: 版本锁定并不排除jar包,而是显示上把所有版本不一致的jar包变成统一一个版本。

总结

  • 尽量在父级pom中定义<dependencyManagement>来管理和统一依赖版本。
  • 对外提供的jar包,尽量不要传递依赖不必要的jar包。
  • 使用maven命令来检测分析依赖:
    • 使用mvn dependency:tree -Dverbose命令来检测jar包冲突。
    • 使用mvn dependency:analyze-only命令来检测声明了但没有被使用的依赖,尽量去掉。
    • 使用mvn dependency:analyze-duplicate命令来分析重复定义的依赖,清理掉重复定义的依赖。

参考文章:segmentfault.com/a/119000002...

相关推荐
今年下半年7 小时前
SpringBoot整合金蝶中间件
spring boot·中间件·maven
vx_BS813301 天前
【项目编号:project51629】Spring Boot 乡村自来水缴费系统:把抄表、水费生成与在线缴费做成一条数字化闭环
java·spring boot·eclipse·tomcat·maven
暮雨哀尘2 天前
JAVA基础练习(四):SpringBoot 实现简易登录功能
java·spring boot·eclipse·maven
hanchenxing3 天前
CI/CD流水线中的构建缓存:从原理到最小可运行示例CI/CD
maven·构建缓存
愛芳芳4 天前
Swagger2 多环境动态配置实战指南
java·后端·maven·springboot·swagger
金玉满堂@bj4 天前
多环境部署方案(开发、测试、生产,搭配Tomcat\+WAR包)
java·tomcat·maven
青春易逝丶4 天前
Maven
java·maven
howard20057 天前
3.3 开发环境 - Maven
maven·安装·配置·阿里镜像源
xinjia_ctrl7 天前
暑假实习总结
git·后端·spring·maven·intellij-idea