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

相关推荐
计算机毕设定制辅导-无忧学长9 小时前
Maven 基础环境搭建与配置(一)
java·maven
计算机毕设指导612 小时前
基于Springboot学生宿舍水电信息管理系统【附源码】
java·spring boot·后端·mysql·spring·tomcat·maven
爱吃南瓜的北瓜14 小时前
Maven之jjwt依赖爆红
java·pycharm·maven
计算机毕设指导620 小时前
基于SpringBoot的城乡商城协作系统【附源码】
java·spring boot·后端·mysql·spring·tomcat·maven
雪落南城1 天前
【Maven】maven加载不到包
java·maven
White graces1 天前
正则表达式效验邮箱格式, 手机号格式, 密码长度
前端·spring boot·spring·正则表达式·java-ee·maven·intellij-idea
drebander2 天前
Maven 构建中的安全性与合规性检查
java·maven
drebander2 天前
Maven 与 Kubernetes 部署:构建和部署到 Kubernetes 环境中
java·kubernetes·maven
丁总学Java3 天前
在IDEA的Maven中(同步所有Maven项目)和(重新加载所有Maven项目)的区别
java·maven·intellij-idea
灬Change3 天前
maven 发布本地jar包到私库
linux·maven·jar