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

相关推荐
smile-yan1 小时前
Provides transitive vulnerable dependency maven 提示依赖存在漏洞问题的解决方法
java·maven
果冻的猿宇宙1 小时前
Maven 中央仓库访问过慢的解决方案--设置国内镜像
maven·镜像·仓库·aliyun·国内镜像·mirror
哆啦 AI 梦1 小时前
【Maven】如何解决Maven循环依赖?
maven·循环依赖
Earnest~1 小时前
Maven极简安装&配置-241223
java·maven
皮蛋很白1 小时前
Maven 环境变量 MAVEN_HOME 和 M2_HOME 区别以及 IDEA 修改 Maven repository 路径全局
java·maven·intellij-idea
w_312345412 小时前
自定义一个maven骨架 | 最佳实践
java·maven·intellij-idea
哆啦 AI 梦18 小时前
【Maven】Maven的classpath
maven·classpath
CodeChampion19 小时前
61.基于SpringBoot + Vue实现的前后端分离-在线动漫信息平台(项目+论文)
java·vue.js·spring boot·后端·node.js·maven·idea
新手小袁_J1 天前
JDK11下载安装和配置超详细过程
java·spring cloud·jdk·maven·mybatis·jdk11
莫名其妙小饼干2 天前
网上球鞋竞拍系统|Java|SSM|VUE| 前后端分离
java·开发语言·maven·mssql