IDEA为我们提供了maven视图,我的是在右侧Maven Projects,
1。点击Maven Projects
2.右击想分析的module,选择show dependency
3.查看视图,选择冲突包,可以查看到被引用情况
Maven中 jar包冲突原理与解决办法
https://blog.csdn.net/noaman_wgs/article/details/81137893
Maven中jar包冲突是开发过程中比较常见而又令人头疼的问题,我们需要知道 jar包冲突的原理,才能更好的去解决jar包冲突的问题。本文将从jar包冲突的原理和解决两个方面阐述Maven中jar包冲突的解决办法。
一、Maven中jar包冲突产生原因
MAVEN项目运行中如果报如下错误:
Caused by:java.lang.NoSuchMethodError
Caused by: java.lang.ClassNotFoundException
1
2
3
十有八九是Maven jar包冲突造成的。那么jar包冲突是如何产生的?
首先我们需要了解jar包依赖的传递性。
1、依赖传递
当我们需要A的依赖的时候,就会在pom.xml中引入A的jar包;而引入的A的jar包中可能又依赖B的jar包,这样Maven在解析pom.xml的时候,会依次将A、B 的jar包全部都引入进来。
举个例子:
在Spring Boot应用中导入Hystrix和原生Guava的jar包:
<!--原生Guava API-->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>20.0</version>
</dependency>
<!--hystrix依赖(包含对Guava的依赖)-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>1.4.4.RELEASE</version>
</dependency>
利用Maven Helper插件得到项目导入的jar包依赖树:
从图中可以看出Hystrix包含对Guava jar包依赖的引用: Hystrix -> Guava,所以在引入Hystrix的依赖的时候,会将Guava的依赖也引入进来。
2、jar包冲突原理
那么jar包是如何产生冲突的?
假设有如下依赖关系:
A->B->C->D1(log 15.0):A中包含对B的依赖,B中包含对C的依赖,C中包含对D1的依赖,假设是D1是日志jar包,version为15.0
E->F->D2(log 16.0):E中包含对F的依赖,F包含对D2的依赖,假设是D2是同一个日志jar包,version为16.0
当pom.xml文件中引入A、E两个依赖后,根据Maven传递依赖的原则,D1、D2都会被引入,而D1、D2是同一个依赖D的不同版本。
当我们在调用D2中的method1()方法,而D1中是15.0版本(method1可能是D升级后增加的方法),可能没有这个方法,这样JVM在加载A中D1依赖的时候,找不到method1方法,就会报NoSuchMethodError的错误,此时就产生了jar包冲突。
注:
如果在调用method2()方法的时候,D1、D2都含有这个方法(且升级的版本D2没有改动这个方法,这样即使D有多个版本,也不会产生版本冲突的问题。)
举个例子:
利用Maven Helper插件分析得出:Guava这个依赖包产生冲突。
我们之前导入了Guava的原生jar包,版本号是20.0;而现在提示Guava产生冲突,且冲突发生位置是Hystrix所在的jar包,所以可以猜测Hystrix中包含了对Guava不同版本的jar包的引用。
为了验证我们的猜想,使用Maven Helper插件打印出Hystrix依赖的jar tree:
可以看到:Hystrix jar中所依赖的Guava jar包是15.0版本的,而我们之前在pom.xml中引入的原生Guava jar包是20.0版本的,这样Guava就有15.0 与20.0这两个版本,因此发生了jar包冲突。
二、 Maven中jar包冲突的解决方案
Maven 解析 pom.xml 文件时,同一个 jar 包只会保留一个,那么面对多个版本的jar包,需要怎么解决呢?
1、 Maven默认处理策略
最短路径优先
Maven 面对 D1 和 D2 时,会默认选择最短路径的那个 jar 包,即 D2。E->F->D2 比 A->B->C->D1 路径短 1。
最先声明优先
如果路径一样的话,如: A->B->C1, E->F->C2 ,两个依赖路径长度都是 2,那么就选择最先声明。
2、移除依赖:用于排除某项依赖的依赖jar包
(1)我们可以借助Maven Helper插件中的Dependency Analyzer分析冲突的jar包,然后在对应标红版本的jar包上面点击execlude,就可以将该jar包排除出去。
再刷新以后冲突就会消失。
(2)手动排除
或者手动在pom.xml中使用<exclusion>标签去排除冲突的jar包(上面利用插件Maven Helper中的execlude方法其实等同于该方法):
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>1.4.4.RELEASE</version>
<exclusions>
<exclusion>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</exclusion>
</exclusions>
</dependency>
1
2
3
4
5
6
7
8
9
10
11
mvn分析包冲突命令:
mvn dependency:tree
1
3 版本锁定原则:一般用在继承项目的父项目中
正常项目都是多模块的项目,如moduleA和moduleB共同依赖X这个依赖的话,那么可以将X抽取出来,同时设置其版本号,这样X依赖在升级的时候,不需要分别对moduleA和moduleB模块中的依赖X进行升级,避免太多地方(moduleC、moduleD….)引用X依赖的时候忘记升级造成jar包冲突,这也是实际项目开发中比较常见的方法。
首先定义一个父pom.xml,将公共依赖放在该pom.xml中进行声明:
<properties>
<spring.version>spring4.2.4</spring.version>
<properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.versio}</version>
</dependency>
</dependencies>
</dependencyManagement>
1
2
3
4
5
6
7
8
9
10
11
12
13
这样如moduleA和moduleB在引用Spring-beans jar包的时候,直接使用父pom.xml中定义的公共依赖就可以:
moduleA在其pom.xml使用spring-bean的jar包(不用再定义版本):
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
</dependencies>
1
2
3
4
5
6
moduleB在其pom.xml使用spring-bean的jar包如上类似:
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
</dependencies>
1
2
3
4
5
6
以上就是日常开发中解决Maven冲突的几个小方案,当然实际开发中jar包冲突的问题可能远远比这个更复杂,需要具体问题具体处理。
2018/07/20 15:14:00 in SH.
参考:https://blog.csdn.net/u011955252/article/details/78927427
————————————————
版权声明:本文为CSDN博主「是Guava不是瓜娃」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/noaman_wgs/article/details/81137893
分享到:
相关推荐
"检测工具 jar包冲突"这个主题就是针对这个问题,旨在帮助开发者识别和解决这类冲突。 首先,我们需要理解为什么会出现jar包冲突。这通常是因为项目依赖管理不善导致的。例如,项目A依赖于库X(版本1),同时库Y...
以下是一些关于如何检查和解决`jar`包冲突的关键知识点: 1. **冲突检测**: - **MANIFEST.MF检查**:每个`jar`包的`META-INF/MANIFEST.MF`文件可以列出其依赖项,通过比较不同`jar`包的`MANIFEST.MF`,可以初步...
这种插件的主要功能是分析项目的依赖关系,找出那些未被项目代码引用的jar包,并将其剔除。这样可以显著优化项目结构,减少不必要的资源占用,提高构建速度和运行性能。下面我们将深入探讨这个话题。 首先,了解...
构建maven工程时pom.xml中引入依赖时有红色字体,setting处理了,也将jar包的版本号都试了一遍,还是没解决,后来请教大牛,原来是没连网,maven工程加载了一部分jar包,连网之后自动下载的jar包跟之前的冲突,用这...
3. **避免冲突**:在多模块项目中,相同的文件名可能导致冲突,通过修改JAR名可以避免这个问题。 4. **发布需求**:在发布到应用市场或第三方库仓库时,可能需要根据平台的要求更改文件名。 "Jar包包名修改"工具的...
本篇将深入探讨这个问题,以及如何通过理解ClassLoader的工作原理和使用相关工具来有效地解决jar包冲突。 首先,我们来了解什么是ClassLoader。在Java中,ClassLoader是负责加载类到JVM中的组件。当遇到多个相同类...
描述中提到的"解决安装好汉化包后打不开idea设置的问题",这可能是指在安装了汉化包后,有些用户遇到了无法打开IntelliJ IDEA设置的情况。这种情况通常发生在汉化过程中某些配置文件没有正确配置或者与原有系统设置...
标题“asm.jar包冲突”揭示了我们正在讨论的是一个与Java编程语言相关的技术问题,特别是涉及到ASM库的使用。ASM是一个流行的Java字节码操控和分析框架,它被广泛用于动态代理、字节码生成以及代码分析等场景。在...
在实际操作中,可能会遇到一些坑,例如依赖冲突、jar包未正确打包导致的运行错误等。解决这些问题通常需要检查pom.xml的配置,确认所有的依赖版本协调一致,且打包过程中没有遗漏任何必要的资源文件。对于运行错误,...
### IntelliJ IDEA 批量导出Maven项目依赖的jar包 #### 一、背景与目的 在Java开发过程中,我们经常需要使用各种第三方库或框架,这些通常是以jar包的形式存在。为了方便项目的构建和部署,我们需要将这些依赖的jar...
"idea中解决maven包冲突的问题(maven helper)" Idea 中解决 Maven 包冲突的问题是日常开发中经常会遇到的一个问题。在 Idea 中,解决 Maven 包冲突的问题可以使用 Maven Helper 插件,该插件可以帮助我们快速地...
为了简化项目结构、减少资源占用以及方便管理,开发者有时会选择将多个JAR包合并成一个单一的JAR包。这个过程被称为JAR文件的合并。本文将详细讲解如何进行这项操作,并分享一个实用的合并工具。 首先,理解JAR文件...
5. **jar冲突**:当多个jar包包含相同类时,可能导致冲突。使用工具如ProGuard或Shade插件可以对jar进行混淆和重命名,避免冲突。 6. **MANIFEST.MF**:manifest文件是jar包的一部分,可以包含版本信息、版权信息,...
- 检查汉化包是否与IDEA版本匹配,不同版本的IDEA可能需要不同的汉化包。 - 在安装汉化包前,最好先备份原有的配置文件,以防意外情况发生。 - 若遇到界面显示异常或部分功能失效,可能是汉化不完全或与某些插件冲突...
在Java开发过程中,引入外部库或jar包是常见的操作,特别是在使用IntelliJ IDEA这样的集成开发环境(IDE)时。本文将详细介绍如何在IntelliJ IDEA中高效地导入jar包,确保它们能被项目正确识别并引用。 首先,我们...
创建jar包通常通过`jar`命令行工具或集成开发环境(IDE)如Eclipse、IntelliJ IDEA等完成。基本的`jar`命令格式为`jar cvf jar_file_name.jar file_list`,其中`c`表示创建,`v`表示详细模式,`f`指定jar文件名,`...
可以通过IDE(如Eclipse、IntelliJ IDEA)的构建工具(如Maven、Gradle)来管理这些依赖,自动下载和引入必要的JAR包,确保项目可以顺利编译和运行。 总的来说,Java的JAR包在软件开发中扮演着关键角色,它们封装了...
总的来说,处理Spring与Hibernate的包冲突需要对Java项目的构建系统有深入理解,熟悉Maven或Gradle的依赖管理,以及对Spring和Hibernate的工作原理有清晰的认识。通过合理的配置管理和版本控制,可以有效地避免和...
"工程中jar包管理工具---ivy"的出现,就是为了有效地解决这个问题。Ivy是一个由Apache Ant项目维护的依赖管理工具,它允许开发者以声明式的方式管理项目所依赖的外部库,从而实现对JAR包的高效管理。这个工具的引入...