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

管理包依赖是 Maven 核心功能之一,下面通过如何引入 jar 包;如何解析 jar 包依赖;包冲突是如何产生;如何解决包冲突;依赖管理解决什么问题;什么是依赖范围;使用包依赖的最佳实践等 6 个问题来介绍。

如何引入 jar 包

在代码开发时,如果需要使用第三方 jar 包提供的类库,那么需要在 pom.xml 加入该 jar 包依赖。 例如:使用 zookeeper client

     <!-- https://mvnrepository.com/artifact/org.apache.hadoop/zookeeper --><dependency><groupId>org.apache.hadoop</groupId><artifactId>zookeeper</artifactId><version>3.3.1</version></dependency></dependencies>

Maven 如何解析 jar 包依赖——传递依赖

如上所述,在 pom.xml 中引入 zookeeper jar 包依赖,当 Maven 解析该依赖时,需要引入的 jar 包不仅仅只有 zookeeper,还会有 zookeeper 内部依赖的 jar 包,还会有 zookeeper 内部依赖的 jar 包依赖的 jar 包…,依赖关系不断传递,直至没有依赖。
例如:上述 pom.xml 引入 zookeeper 依赖,实际引入的 jar 包有

包冲突如何产生?

举个例子:假设 A->B->C->D1, E->F->D2,D1,D2 分别为 D 的不同版本。
如果 pom.xml 文件中引入了 A 和 E 之后,按照 Maven 传递依赖原则,工程内需要引入的实际 Jar 包将会有:A B C D1 和 E F D2,因此 D1,D2 将会产生包冲突。

如何解决包冲突

Maven 解析 pom.xml 文件时,同一个 jar 包只会保留一个,这样有效的避免因引入两个 jar 包导致的工程运行不稳定性。

Maven 默认处理策略

最短路径优先

Maven 面对 D1 和 D2 时,会默认选择最短路径的那个 jar 包,即 D2。E->F->D2 比 A->B->C->D1 路径短 1。

最先声明优先

如果路径一样的话,举个�: A->B->C1, E->F->C2 ,两个依赖路径长度都是 2,那么就选择最先声明。

移除依赖

如果我们不想通过 A->B->->D1 引入 D1 的话,那么我们在声明引入 A 的时候将 D1 排除掉,这样也避免了包冲突。
举个�:将 zookeeper 的 jline 依赖排除

<dependency><groupId>org.apache.hadoop</groupId><artifactId>zookeeper</artifactId><version>3.3.1</version><exclusions><exclusion><groupId>jline</groupId><artifactId>jline</artifactId></exclusion></exclusions>
</dependency>

检测包冲突工具

mvn dependency:help
mvn dependency:analyze
mvn dependency:tree
mvn dependency:tree -Dverbose

详细参考:

mvn dependency
mvn dependency:tree

依赖管理解决什么问题
当同一个工程内有多个模块时,并且要求多个模块使用某个 jar 包的相同版本,为了方便统一版本号,升级版本号,需要提取出一个父亲模块来管理子模块共同依赖的 jar 包版本。
举个例子:有两个模块 projectA, projectB,它们的依赖分别如下所示:
projectA:

<project>...<dependencies><dependency><groupId>group-a</groupId><artifactId>artifact-a</artifactId><version>1.0</version><exclusions><exclusion><groupId>group-c</groupId><artifactId>excluded-artifact</artifactId></exclusion></exclusions></dependency><dependency><groupId>group-a</groupId><artifactId>artifact-b</artifactId><version>1.0</version><type>bar</type><scope>runtime</scope></dependency></dependencies>
</project>
projectB:<project>...<dependencies><dependency><groupId>group-c</groupId><artifactId>artifact-b</artifactId><version>1.0</version><type>war</type><scope>runtime</scope></dependency><dependency><groupId>group-a</groupId><artifactId>artifact-b</artifactId><version>1.0</version><type>bar</type><scope>runtime</scope></dependency></dependencies>
</project>

projectA 和 projectB 共同依赖了 group-a/artifact-b/1.0,提取公共依赖,生成 parent, parent 依赖如下:

<project>...<dependencyManagement><dependencies><dependency><groupId>group-a</groupId><artifactId>artifact-b</artifactId><version>1.0</version><type>bar</type><scope>runtime</scope></dependency></dependencies></dependencyManagement>
</project>

则 projectA 和 projectB 均不需要指定 group-a/artifact-b 的 version 信息,未来升级 version 信息时,只需要在 parent 内部指定。

projectA:

<project>...
<parent>
<groupId>group-a</groupId><artifactId>artifact-b</artifactId><version>1.0</version>
</parent><dependencies><dependency><groupId>group-a</groupId><artifactId>artifact-a</artifactId><version>1.0</version><exclusions><exclusion><groupId>group-c</groupId><artifactId>excluded-artifact</artifactId></exclusion></exclusions></dependency><dependency><groupId>group-a</groupId><artifactId>artifact-b</artifactId></dependency></dependencies>
</project>
projectB:<project>...<dependencies><dependency><groupId>group-c</groupId><artifactId>artifact-b</artifactId><version>1.0</version><type>war</type><scope>runtime</scope></dependency><dependency><groupId>group-a</groupId><artifactId>artifact-b</artifactId></dependency></dependencies>
</project>

依赖范围

如果不显示执行 属性时,默认 compile。
scope 有哪些属性:compile, provided, runtime, test, system 等。
详细参考:依赖范围

最佳实践

(1)项目中源代码使用的 jar 包一定在 pom.xml 中显示引用。
(2)经常 check 一下包冲突,检查是否需要处理。
(3)当使用多个模块时,parent 一定要使用包管理模块来规范 Jar 包版本,而不是包依赖模块直接引入依赖。 dependencyManagement vs dependencies

Maven中 jar包冲突原理与解决办法依赖传递相关推荐

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

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

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

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

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

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

  4. Maven之jar包冲突引入非第三方jar

    文章目录 1. jar包冲突问题 2. 解决办法 2.1 Maven Helper插件 2.1.1 安装 Maven Helper 插件 2.1.2 pom.xml 依赖冲突分析 2.1.2.1 打开 ...

  5. Intellij+maven:jar包冲突的解决方法(Hbase和Guava的冲突)

    Intellij+maven:jar包冲突的解决方法(Hbase和Guava的冲突) 参考文章: (1)Intellij+maven:jar包冲突的解决方法(Hbase和Guava的冲突) (2)ht ...

  6. 解决Maven的jar包冲突问题

    解决Maven的jar包冲突问题 参考文章: (1)解决Maven的jar包冲突问题 (2)https://www.cnblogs.com/NyanKoSenSei/p/11425944.html 备 ...

  7. springboot依赖lib外置打成压缩包,以及snapshot依赖jar包ClassNotFoundExcepttion异常的解决办法

    springboot依赖lib外置打成压缩包,以及snapshot依赖jar包ClassNotFoundExcepttion异常的解决办法 mvn插件 assembly压缩zip assembly.x ...

  8. 阿里云SDK和SpringBoot maven项目中jar包冲突的解决办法

    stringboot项目在引用阿里云短信sdk时,出现jar包冲突问题,项目可以正常启动,但是启动会报如图错误 解决办法,在maven中查找到冲突的jar,并用exclusions隔离冲突的jar & ...

  9. maven依赖的jar包版本不一样_Maven依赖jar包冲突常见的解决方法

    项目中,经常会遇到ClassNotFound,NoSuchMethod异常,第一反应往往是类路径不对,jar没有正确的引用.第一步判断jar是否加载,还是 加载的jar由于maven依赖管理存在传递依 ...

最新文章

  1. 学习笔记TF064:TensorFlow Kubernetes
  2. android classloader的功能和工作模式,Android中ClassLoader和java中ClassLoader有什么关系和不同...
  3. json数据转换成表格_电子表格会让您失望吗? 将行数据转换为JSON树很容易。
  4. 477.汉明距离总和
  5. C#如何查看DLL文件中的成员
  6. 台式计算机没有usb3.0,新装的win7没有usb驱动完美解决方法(支持usb3.0/usb3.1)
  7. 真无线蓝牙耳机哪个好?四款买了不亏的真无线蓝牙耳机
  8. php 获取xlsx,使用php读取xlsx文件
  9. oppoJava面试!一招彻底帮你搞定HashMap源码,极其重要
  10. 修改CentOS默认yum源地址提高下载速度
  11. 如何在Ubuntu系统下挂载新硬盘(win10+Ubuntu双系统单硬盘挂载新硬盘)
  12. 内推 | 【国企】中国人寿-数据管理与数据分析/成都
  13. 怎样改变照片大小?免费在线图片压缩方法
  14. 算盘在计算机中的应用,中国大学MOOC: 算盘、计算机都是信息处理的工具。
  15. 雷电、夜神、天天、逍遥等模拟器中找不到要下载的软件解决方法
  16. mysql limit sql注入_LIMIT子句中的盲 SQL注入漏洞利用
  17. 人生是一个不断觉悟的过程,成功是一种感悟。
  18. UVA12563 Jin Ge Jin Qu hao
  19. 基于UE4+ OpenCV 的混合现实 (webCamera, mix-reality, blue screen matting)
  20. CAD/CAM/CAE基础(三) 材料加工CAE技术基础

热门文章

  1. 我的醉驾拘留15日记----第二日凌晨 午夜惊梦
  2. 剑指-从尾到头打印链表
  3. CodeForces - 236D Let‘s Play Osu!(概率dp)
  4. CodeForces - 1452E Two Editorials(二阶差分)
  5. PAT (Basic Level) - 1025 反转链表(模拟)
  6. 斐波那契博弈(证明+结论)
  7. 百度贴吧个人主页_百度手机App商店社交应用排行榜,微信连续三个月霸占榜首...
  8. mysql主库宕机能写吗_MYSQL主主切换(主库宕机)_MySQL
  9. VIM进阶-宏Macro
  10. Mysql游标循环遍历