Maven中的依赖冲突
如下图所示的场景:项目需要依赖jar包A(记作jarA)、jar包B(记作jarB),jarA和jarB同时需要依赖jar包C(记作jarC),不同的是,jarA需要的是jarC的1.0版本,jarB需要的是jarC的2.0版本。
那么,Maven会不会同时导入jarC1.0和jarC2.0?
当然不是!
对此,maven有两种策略,
- 第一种,短路径优选策略。
第一条路径:项目依赖jarA,jarA依赖jarE,jarE依赖jarC1.0,即项目->jarA->jarE->jarC1.0。
第二条路径:项目依赖jarB,jarB依赖jarC2.0,即项目->jarB->jarC2.0。
短路径优先,所以最后maven只会导入jarC2.0,不会重复导入jarC1.0。 - 第二种,声明优先策略。
如果引用路径长度相同,则采用声明优先策略。这就和依赖在pom文件中声明的先后顺序有关了。谁在前,就导入谁。
<!-- pom.xml -->
<dependency><groupId></groupId><artifactId>jarA</artifactId><version></version>
</dependency>
<dependency><groupId></groupId><artifactId>jarB</artifactId><version></version>
</dependency>
如上所示,因为jarA的声明在前,所以最后只会导入jarC1.0,不会重复导入jarC2.0。
好了,理论就是这样了。现在来看具体例子吧。
首先,新建一个基本的java项目,然后修改pom文件。
- 例1:添加依赖
commons-logging:1.1
。
<dependencies><!-- https://mvnrepository.com/artifact/commons-logging/commons-logging --><dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.1</version></dependency>
</dependencies>
点击鼠标右键,Diagrams>Show Dependencies查看依赖树,如下所示。
可以看到,commons-logging:1.1依赖log4j:1.2.12,即commons-logging:1.1->log4j:1.2.12。
- 例2:添加依赖
poi:3.5-FINAL
。
<dependencies><!-- https://mvnrepository.com/artifact/org.apache.poi/poi --><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.5-FINAL</version></dependency>
</dependencies>
查看依赖树,如下所示。
可以看到,关于依赖log4j,这里出现了一个冲突。
一条路径是:项目trains03->poi:3.5-FINAL->commons-logging:1.1->log4j:1.2.12。
另一条路径是:项目trains03->poi:3.5-FINAL->log4j:1.2.13。
短路径优先原则,所以maven最终只会导入log4j:1.2.13,所以在External Libraries里我们也只看到了log4j:1.2.13。
- 例3:添加依赖
poi:3.5-FINAL
和commons-beanutils:1.9.4
<dependencies><!-- https://mvnrepository.com/artifact/org.apache.poi/poi --><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.5-FINAL</version></dependency><!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils --><dependency><groupId>commons-beanutils</groupId><artifactId>commons-beanutils</artifactId><version>1.9.4</version></dependency>
</dependencies>
查看依赖树,如下图所示。
关于logg4j的冲突,例2中已经讲过了。
现在来看下关于commons-logging的冲突。
一条路径是:项目trains03->poi:3.5-FINAL->commons-logging:1.1。
另一条路径是:项目trains03->commons-beanutils:1.9.4->commons-logging:1.2。
以上两条路径长度是相同的,所以maven采用了声明优先策略。
pom文件中,poi声明在前,所以maven只导入了commons-logging:1.1。这也是为什么在External Libraries中只看到了commons-logging:1.1。
通常,软件版本都是向后兼容的。举例来说,commons-logging:1.1能提供的api,commons-logging:1.2也都能提供;但commons-logging:1.2能提供的功能,更低版本可能就不支持了。
所以,如果我们希望maven项目导入commons-logging:1.2,而不是commons-logging:1.1,有两个办法:
- 第一个办法:把commons-beanutils:1.9.4的声明前置。
<dependencies><!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils --><dependency><groupId>commons-beanutils</groupId><artifactId>commons-beanutils</artifactId><version>1.9.4</version></dependency><!-- https://mvnrepository.com/artifact/org.apache.poi/poi --><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.5-FINAL</version></dependency>
</dependencies>
- 第二个办法:使用
<exclusions/>
排除依赖。
<dependencies><!-- https://mvnrepository.com/artifact/org.apache.poi/poi --><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.5-FINAL</version><exclusions><exclusion><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId></exclusion></exclusions></dependency><!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils --><dependency><groupId>commons-beanutils</groupId><artifactId>commons-beanutils</artifactId><version>1.9.4</version></dependency>
</dependencies>
使用<exclusions/>
排除依赖还可以应用在这么一种场景中。
项目依赖jarA,jarA同时依赖jarB、jarC,但项目其实并不依赖jarB,如下图所示。
上图其实就是依赖传递。默认情况下,maven会将所有这些依赖,不论是直接依赖还是间接依赖全部下载到本地。
但是,既然项目不需要jarB,完全可以将其排除在外,这时就可以使用<exclusions/>
,如下所示。
<dependencies><dependency><groupId>org.example</groupId><artifactId>jarA</artifactId><version>1.0-SNAPSHOT</version><exclusions><exclusion><groupId>org.example</groupId><artifactId>jarB</artifactId></exclusion></exclusions></dependency>
</dependencies>
如此一来,依赖树就变成了下图右侧的样子了。
Maven中的依赖冲突相关推荐
- Maven中 jar包冲突原理与解决办法依赖传递
Maven中 jar包冲突原理与解决办法&依赖传递 管理包依赖是 Maven 核心功能之一,下面通过如何引入 jar 包:如何解析 jar 包依赖:包冲突是如何产生:如何解决包冲突:依赖管理解 ...
- Maven中scope依赖范围和依赖的传递性
Maven中使用 scope 来指定当前包的依赖范围和依赖的传递性.常见的可选值有:compile, provided, runtime, test, system 等.scope 主要是用在 pom ...
- Maven中jar包冲突的解决方式
现象 创建一个maven工程,引入spring-context包. <dependency><groupId>org.springframework</groupId&g ...
- maven中把依赖的JAR包一起打包(转)
转自:http://lvjun106.iteye.com/blog/1849803 这里所用到的MAVEN-PLUGIN是MAVNE-ASSEMBLY-PLUGIN 官方网站是:http://mave ...
- 工程子模块引用依赖与父pom中的依赖冲突解决方法
例如:父pom中引用了针对mybatis的引用依赖,子模块中引用了mybatis-plus依赖,形成引用冲突,启动失败. 父pom <!-- mybatis --> <depende ...
- Maven中可选依赖(optional)和依赖排除(exclusion)的用法
前面必读的话 Optional和Exclusions都是用来排除jar包依赖使用的,两者在使用上却是相反.Optional表示可选择的,Exclusions表示排除 Optional定义后,该依赖只能 ...
- Maven中通过依赖坐标导入jar包
Maven下的Java项目执行结果展示 其实在maven仲只需要导入依赖坐标就可以代替手动导jar包.在pom.xml中使用标签引入依赖. 首先看一下项目的结构: Java中的Servlet代码如下: ...
- Maven中jar版本冲突问题的解决
如:在父工程中引入了struts-core,hibernate-core,发现jar包是有冲突的.javassist存在版本上冲突. 方法一: <dependency><groupI ...
- Maven中 jar包冲突的解决办法
问题描述:启动工程报如下错误: SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:fil ...
最新文章
- SH 脚本注意事项之 IF 判断
- JAVA怎么查找错误,如何调试错误“符号查找错误:未定义符号”
- 机器学习Sklearn实战——手写线性回归
- 人工智能取代医生AI画出鼻咽癌放疗靶区,准确性与医生相当
- r graphics installing package
- 十、深入Java字符串(下篇)
- PHP之composer切换国内源
- Redis面试题相关知识整理
- PHP动态设计的设计流程,《PHP设计模式介绍》第十四章 动态记录模式
- uniaccess进程无法结束 拒绝访问_嵌入式Linux编程——程序员小白不懂的进程、信号量、并发、互斥...
- php 微信小程序 循环 多选,微信小程序实现多选功能
- windows CMD.exe下写路径太长的解决方案
- 在redis取数据若存在直接取,不存在在db中取,并放到缓存中
- excel文件导出相应数据统计内容
- bzoj2763 [JLOI2011]飞行路线
- 计算机公益活动策划书,社会公益爱心活动策划方案模板
- 大数据数据库(HBase)
- 测量学9_计算机地图绘图基础及数字地图中DEM应用
- WPS Office 2005的评议
- vue中使用Vue-i18n插件实现页面中英文切换详细教程
热门文章
- linux 下 scp 的用法
- ajax回调函数 异步延迟
- ajax怎么实现回调,jQuery API学习之ajax与回调对象篇
- python全栈示例_Python全栈之路--Django ORM详解
- matlab 根据长轴,短轴,中心坐标画椭圆
- 68000多只海洋动物、占地18.3万平米,这才是全球最大海洋水族馆该有的气势!...
- 一键清除锁屏密码:苹果手机忘记锁屏密码的解决方案
- msvcr120.dll丢失怎样修复?msvcr120.dll文件修复方法
- centos安装cerebro
- 资源分享|免费注册申请永久的eu.org顶级域名创建属于自己的域名,再也不用给博客域名续费了!...