解决maven依赖冲突,这篇就够了!

本文详细介绍了什么是依赖冲突,分析了Maven的依赖原则,包括路径最近者优先和第一声明者优先,并展示了如何通过排除依赖来解决冲突。通过实例演示了如何使用Maven Helper插件分析和解决依赖冲突,最后强调了解决依赖冲突时需考虑版本兼容性和项目影响。
摘要由CSDN通过智能技术生成

一、前言

什么是依赖冲突

依赖冲突是指项目依赖的某一个jar包,有多个不同的版本,因而造成了包版本冲突。

依赖冲突的原因

我们在maven项目的pom中 一般会引用许许多多的dependency。例如,项目A有这样的依赖关系:

<span style="color:#4b4b4b"><span style="background-color:#ffffff"><code class="language-xml">A -> C -> X(1.0)
B -> D -> X(2.0)
</code></span></span>

X是A的传递性依赖,但是两条依赖路径上有两个版本的X,那么哪个X会被Maven解析使用呢? 两个版本都被解析显然是不对的,因为那会造成依赖重复,因此必须选择一个。

至于怎么选肯定有它的规则(下面会讲),这里我们先假设最终引用的X(1.0)版本,这样会不会有问题呢?

当然会有的

1、你想如果B引用X(2.0)的新创建的类,但因为最终被解析的是X(1.0),所以就会出现很典型的NoClassDefFoundError 或ClassNotFoundException依赖冲突报错。

2、如果B引用X(2.0)的新创建的方法,但因为最终被解析的是X(1.0),所以就会抛出 NoSuchMethodError系统异常。

但换种角度,如果最终解析的是X(2.0),就没问题了吗?

那也不一定

1、如果X(2.0)删掉了X(1.0)的一些类,但A已经引用了,同样也会报NoClassDefFoundError或者ClassNotFoundException错误。

2、如果X(2.0)删掉了X(1.0)的一些方法,但A已经引用了,同样也会报NoSuchMethodError错误。

所以说具体问题还需具体分析,到底采用哪个版本还需要看实际项目。也可能我们需要升级对应的A或者B的版本才能解决问题。

如果有两个版本的X,Maven是依据什么原则来选择解析哪个X呢?

二、maven依赖原则

maven依赖主要有两大原则

1、路径最近者优先

相同jar不同版本,根据依赖的路径长短来决定引入哪个依赖。

举例

<span style="color:#4b4b4b"><span style="background-color:#ffffff"><code class="language-rust">依赖链路一:A <span style="color:#444a44">-></span> B <span style="color:#444a44">-></span> C <span style="color:#444a44">-></span> <span style="color:#a6e22e">X</span>(<span style="color:#ae81ff">1.0</span>)
依赖链路二:F <span style="color:#444a44">-></span> D <span style="color:#444a44">-></span> <span style="color:#a6e22e">X</span>(<span style="color:#ae81ff">2.0</span>)
</code></span></span>

该例中X(1.0)的路径长度为3,而X(2.0)的路径长度为2,因此X(2.0)会被解析使用。依赖调解第一原则不能解决所有问题,比如这样的依赖关系:

<span style="color:#4b4b4b"><span style="background-color:#ffffff"><code class="language-rust">A <span style="color:#444a44">-></span> B <span style="color:#444a44">-></span> <span style="color:#a6e22e">Y</span>(<span style="color:#ae81ff">1.0</span>)
c <span style="color:#444a44">-></span> D <span style="color:#444a44">-></span> <span style="color:#a6e22e">Y</span>(<span style="color:#ae81ff">2.0</span>)
</code></span></span>

Y(1.0)和Y(2.0)的依赖路径长度是一样的,都为2。Maven定义了依赖调解的第二原则:

2、第一声明者优先

在依赖路径长度相等的前提下,在POM中依赖声明的顺序决定了谁会被解析使用,顺序最前的那个依赖优胜。该例中,如果A的依赖声明在C之前,那么Y (1.0)就会被解析使用.

注意 子pom内声明的优先于父pom中的依赖。

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值