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...

相关推荐
尘浮生2 小时前
Java项目实战II基于Spring Boot的光影视频平台(开发文档+数据库+源码)
java·开发语言·数据库·spring boot·后端·maven·intellij-idea
aloha_78910 小时前
从零记录搭建一个干净的mybatis环境
java·笔记·spring·spring cloud·maven·mybatis·springboot
尢词12 小时前
SpringMVC
java·spring·java-ee·tomcat·maven
wrx繁星点点12 小时前
享元模式:高效管理共享对象的设计模式
java·开发语言·spring·设计模式·maven·intellij-idea·享元模式
前 方14 小时前
若依入门案例
java·spring boot·maven
咕哧普拉啦14 小时前
乐尚代驾十订单支付seata、rabbitmq异步消息、redisson延迟队列
java·spring boot·mysql·spring·maven·乐尚代驾·java最新项目
不像程序员的程序媛16 小时前
mybatisgenerator生成mapper时报错
maven·mybatis
移民找老国16 小时前
加拿大移民新风向
java-ee·maven·phpstorm·visual studio code·nio
LUwantAC16 小时前
Java学习路线:Maven(三)继承关系
java·学习·maven
尘浮生20 小时前
Java项目实战II基于Spring Boot的问卷调查系统的设计与实现(开发文档+数据库+源码)
java·开发语言·数据库·spring boot·后端·maven·intellij-idea