如下图所示的场景:项目需要依赖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-FINALcommons-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中的依赖冲突相关推荐

  1. Maven中 jar包冲突原理与解决办法依赖传递

    Maven中 jar包冲突原理与解决办法&依赖传递 管理包依赖是 Maven 核心功能之一,下面通过如何引入 jar 包:如何解析 jar 包依赖:包冲突是如何产生:如何解决包冲突:依赖管理解 ...

  2. Maven中scope依赖范围和依赖的传递性

    Maven中使用 scope 来指定当前包的依赖范围和依赖的传递性.常见的可选值有:compile, provided, runtime, test, system 等.scope 主要是用在 pom ...

  3. Maven中jar包冲突的解决方式

    现象 创建一个maven工程,引入spring-context包. <dependency><groupId>org.springframework</groupId&g ...

  4. maven中把依赖的JAR包一起打包(转)

    转自:http://lvjun106.iteye.com/blog/1849803 这里所用到的MAVEN-PLUGIN是MAVNE-ASSEMBLY-PLUGIN 官方网站是:http://mave ...

  5. 工程子模块引用依赖与父pom中的依赖冲突解决方法

    例如:父pom中引用了针对mybatis的引用依赖,子模块中引用了mybatis-plus依赖,形成引用冲突,启动失败. 父pom <!-- mybatis --> <depende ...

  6. Maven中可选依赖(optional)和依赖排除(exclusion)的用法

    前面必读的话 Optional和Exclusions都是用来排除jar包依赖使用的,两者在使用上却是相反.Optional表示可选择的,Exclusions表示排除 Optional定义后,该依赖只能 ...

  7. Maven中通过依赖坐标导入jar包

    Maven下的Java项目执行结果展示 其实在maven仲只需要导入依赖坐标就可以代替手动导jar包.在pom.xml中使用标签引入依赖. 首先看一下项目的结构: Java中的Servlet代码如下: ...

  8. Maven中jar版本冲突问题的解决

    如:在父工程中引入了struts-core,hibernate-core,发现jar包是有冲突的.javassist存在版本上冲突. 方法一: <dependency><groupI ...

  9. Maven中 jar包冲突的解决办法

    问题描述:启动工程报如下错误: SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:fil ...

最新文章

  1. SH 脚本注意事项之 IF 判断
  2. JAVA怎么查找错误,如何调试错误“符号查找错误:未定义符号”
  3. 机器学习Sklearn实战——手写线性回归
  4. 人工智能取代医生AI画出鼻咽癌放疗靶区,准确性与医生相当
  5. r graphics installing package
  6. 十、深入Java字符串(下篇)
  7. PHP之composer切换国内源
  8. Redis面试题相关知识整理
  9. PHP动态设计的设计流程,《PHP设计模式介绍》第十四章 动态记录模式
  10. uniaccess进程无法结束 拒绝访问_嵌入式Linux编程——程序员小白不懂的进程、信号量、并发、互斥...
  11. php 微信小程序 循环 多选,微信小程序实现多选功能
  12. windows CMD.exe下写路径太长的解决方案
  13. 在redis取数据若存在直接取,不存在在db中取,并放到缓存中
  14. excel文件导出相应数据统计内容
  15. bzoj2763 [JLOI2011]飞行路线
  16. 计算机公益活动策划书,社会公益爱心活动策划方案模板
  17. 大数据数据库(HBase)
  18. 测量学9_计算机地图绘图基础及数字地图中DEM应用
  19. WPS Office 2005的评议
  20. vue中使用Vue-i18n插件实现页面中英文切换详细教程

热门文章

  1. linux 下 scp 的用法
  2. ajax回调函数 异步延迟
  3. ajax怎么实现回调,jQuery API学习之ajax与回调对象篇
  4. python全栈示例_Python全栈之路--Django ORM详解
  5. matlab 根据长轴,短轴,中心坐标画椭圆
  6. 68000多只海洋动物、占地18.3万平米,这才是全球最大海洋水族馆该有的气势!...
  7. 一键清除锁屏密码:苹果手机忘记锁屏密码的解决方案
  8. msvcr120.dll丢失怎样修复?msvcr120.dll文件修复方法
  9. centos安装cerebro
  10. 资源分享|免费注册申请永久的eu.org顶级域名创建属于自己的域名,再也不用给博客域名续费了!...