maven冲突如何解决? 为什么会出现这种冲突?我们需要知道 jar包冲突的原理,才能更好的去解决jar包冲突的问题。
一、为什么会出现依赖冲突
首先要说明Maven的依赖管理,maven在依赖管理中有几个原则
- 依赖是使用Maven坐标来定位的,而Maven坐标主要由GAV(groupId, artifactId, version)构成。如果两个相同的依赖包,如果groupId, artifactId,version不同,那么maven也认为这两个是不同的。
- 依赖会传递,A依赖了B,B依赖了C,那么A的依赖中就会出现B和C。
- Maven对同一个groupId, artifactId的冲突仲裁,不是以version越大越保留,而是依赖路径越短越优先,然后进行保留。
- 依赖的scope会影响依赖的影响范围。
出现这种问题的象征,比如一下问题:很有可能是你系统中出现了依赖冲突
Caused by:java.lang.NoSuchMethodError
Caused by: java.lang.ClassNotFoundException
Caused by:java.lang.LinkageError
为什么会出现冲突呢?
使用pom.xml文件添加dependecy(依赖)的时候,虽然,我们定义的dependecy不可能存在同一个依赖有两个版本,但是由于依赖还会引用别的依赖,这个时候就会有依赖冲突的情况出现。比如我们的项目引入两个依赖A、B,而A还引入依赖C1.0,B引入依赖C2.0,这个时候就面临该用哪个版本的C的问题了。如下图所示。
二、Maven中jar包冲突的解决方案
Maven 解析 pom.xml 文件时,同一个 jar 包只会保留一个,那么面对多个版本的jar包,需要怎么解决呢?
1.maven如何自动解决冲突的依赖
maven解决版本冲突主要是两个原则。
- 路径最短原则:如上图E1的路径是“项目-A-E1”,E2的路径是“项目-B-F-E2”,因为E1路径比E2短,所以最终会选择E1而不用E2。
- 优先声明原则:当出现路径长短相同的时候,谁先声明就用谁。如F1和F2的路径距离相同,但是由于F1比F2先声明(B比C先声明),所以最终使用F1。
2、手动解决冲突
(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>
mvn分析包冲突命令:
mvn dependency:tree
3、在Intellij下如何查看冲突
打开pom.xml,在文件里,右键,如下图所式:
红线部分就是有冲突并被舍弃的依赖。选择其中一个依赖,会看到所有相同依赖的不同版本都会被 红虚线 连接起来。这些不同版本的依赖中一定会有一个与父依赖没有用红实线连接的,而是用正常的蓝线连接,这个就是被选择并使用的依赖。如下图: