Maven中关于jar包冲突的2种排查方案及3种解决方式

在实际开发中,多模块项目常会使用Maven进行包管理。在poml文件中进行包依赖时,常存在引入一个jar包中默认依赖了其他的jar包的情况。这样很容易导致jar包冲突,从而产生一些诡异问题,如版本问题导致的类、方法找不到等。

下面我们将聊聊具体关于依赖冲突产生的原因、排查方式以及解决的方案。


1.什么是依赖传递

举个简单例子,比如一个多模块项目依赖关系如下图。其中bepe-dal引入了common-lib,当bepe-manager模块中引入bepe-dal时,common-lib这个依赖也会被引入到bepe-manager模块中,这个就是依赖传递。


2. 什么是依赖冲突

依赖冲突,实际上就是jar包依赖冲突。

即当模块中引入很多jar包时,如果其中存在着groupId和artifactId 一样,但是version不一样的两个jar包,这就是依赖冲突。

那么在应用时会选用哪一个version呢?这就是我们接下来要讨论的冲突解决方式。


3. 如何解决依赖冲突

  • 最短路径原则
  • 声明优先原则
  • 依赖排除

3.1 最短路径原则

当存在groupId和artifactId一致但是version不一致的jar包冲突时,模块会自动选择距离自己路径短的包。如:bepe-manager到common-lib(1.0)的距离为2,bepe-manager到common-lib(2.0)的距离为1,就会选择距离短的common-lib(2.0),这就是最短路径原则。

Maven中关于jar包冲突的2种排查方案及3种解决方式

3.2 声明优先原则

当冲突包路径距离长度一样时,这个时候就会依据其在pom文件中声明的先后顺序。

Maven中关于jar包冲突的2种排查方案及3种解决方式

在manager模块pom.xml中,如果先引用bepe-common,就会用2.0版本的common-lib。

<dependency> 
    <groupId>com.company.bepe</groupId> 
    <artifactId>bepe-common</artifactId> 
    <version>2.2</version> 
</dependency> 
<dependency> 
    <groupId>om.company.bepe</groupId> 
    <artifactId>bepe-dal</artifactId> 
    <version>2.2</version> 
</dependency> 

3.3 依赖排除

通过<exclusions>标签将不需要依赖的包进行排除,通过这种方式我们就灵活进行取舍。但是该如何发现冲突呢?接下来将讨论关于依赖冲突排查的方式。

Maven中关于jar包冲突的2种排查方案及3种解决方式


4. 依赖冲突情况该怎么排查?

我们可以借助一些插件工具帮助找出冲突jar的具体位置。下面分享一下我在项目中排查并解决包冲突的两种方式。

  • maven-enforcer-plugin 插件
  • Maven Helper 插件

4.1 maven-enforcer-plugin插件

Maven提供了Maven-Enforcer-Plugin插件 , 用来校验约定遵守情况,比依赖 jar 包的版本等等。当规则检查不通过的时候则会构建失败。

【1】在pom.xml中引入该插件

Maven中关于jar包冲突的2种排查方案及3种解决方式

rules内则是定义校验规则,通过配置<dependencyConvergence/>可实现重复依赖检测。也支持自定义做一些其他检验如版本检验等。关于maven-enforcer-plugin插件rules的其他配置用法,感兴趣的朋友们,可以去查阅其相关的资料。

<rules>
    <requireMavenVersion>
	    <version>3.0.4</version>
	</requireMavenVersion>
	<!--要求JDK版本)-->
	<requireJavaVersion>
		<version>6.0</version>
	</requireJavaVersion>
	<bannedDependencies>
	    <!--是否检查传递性依赖(间接依赖)-->
		<searchTransitive>true</searchTransitive>
		<excludes>
		    <exclude>junit:junit</exclude>
		</excludes>
		<message>must use TestNG</message>
	</bannedDependencies>
</rules>

【2】配置好插件后进行项目构建,当存在包冲突时会在console中打印出来。

Maven中关于jar包冲突的2种排查方案及3种解决方式

【3】依据信息便可将不需要的jar包通过<exclusions>排除掉。

Maven中关于jar包冲突的2种排查方案及3种解决方式


4.2 Maven Helper

使用IntelliJ IDE的Maven helper插件方便找到和排除冲突的依赖项

【1】command+, 打开工具的设置窗口

【2】设置搜索中输入plugin

【3】在Marketplace table页面中搜索Maven Helper,并安装

【4】重启后即可使用,打开pom文件后,文件下面会多出Dependency Analyzer这一个tab。

进入Dependency Analyzer视图之后有三个查看选项,

Conflicts(冲突)

All Dependencies as List(列表形式查看所有依赖)

All Dependencies as Tree(树结构查看所有依赖)

通过查看信息后再做出对应的依赖冲突处理。

Maven中关于jar包冲突的2种排查方案及3种解决方式

总结

关于依赖冲突解决方式有三种:最短路径原则、声明优先原则、依赖排除。

在没有手动进行依赖排除的情况下,会依据最短路径原则、声明优先原则来选择jar包。

关于依赖冲突排查可借助如maven-enforcer-plugin 与Maven Helper 插件。根据实际情况及环境,选择组合最优的解决方案解决依赖冲突问题。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

洒家肉山大魔王

您的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值