您的位置:首页 > 财经 > 金融 > maven 依赖冲突

maven 依赖冲突

2024/12/24 21:09:03 来源:https://blog.csdn.net/tszc95/article/details/140071980  浏览:    关键词:maven 依赖冲突

依赖冲突

1、对于 Maven 而言,同一个 groupId 同一个 artifactId 下,只能使用一个 version。

        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-math3 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-math3</artifactId><version>3.6.1</version></dependency><!-- 只会使用 3.6 这个版本的依赖 --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-math3</artifactId><version>3.6</version></dependency>

若相同类型但版本不同的依赖存在于同一个 pom 文件,只会引入后一个声明的依赖。

2、项目的两个依赖同时引入了某个依赖。

  • 最短路径优先(Nearest Definition Wins):即优先选择依赖树中离项目最近的版本。
  • 先声明者优先(First Declaration Wins):即优先选择在 pom.xml 中首次声明的依赖版本。

举个例子,项目存在下面这样的依赖关系:

依赖链路一:A -> B -> C -> X(1.0)
依赖链路二:A -> D -> X(2.0)

这两条依赖路径上有两个版本的 X,为了避免依赖重复,Maven 只会选择其中的一个进行解析。

哪个版本的 X 会被 Maven 解析使用呢?

        Maven 在遇到这种问题的时候,会遵循 路径最短优先声明顺序优先 两大原则。解决这个问题的过程也被称为 Maven 依赖调解

最短路径优先:

依赖链路一:A -> B -> C -> X(1.0) // dist = 3
依赖链路二:A -> D -> X(2.0) // dist = 2

依赖链路二的路径最短,因此,X(2.0)会被解析使用。

不过,你也可以发现。路径最短优先原则并不是通用的,像下面这种路径长度相等的情况就不能单单通过其解决了:

先声明者优先:举个例子,项目存在下面这样的依赖关系:

依赖链路一:A -> B -> X(1.0)
依赖链路二:A -> D -> X(2.0)

这两条依赖路径上有两个版本的 X,为了避免依赖重复,Maven 只会选择其中的一个进行解析。

<!-- A pom.xml -->
<dependencies>...dependency B...dependency D
</dependencies>

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

排除依赖

单纯依赖 Maven 来进行依赖调解,在很多情况下是不适用的,需要我们手动排除依赖。

举个例子,当前项目存在下面这样的依赖关系:

依赖链路一:A -> B -> C -> X(1.5) // dist = 3
依赖链路二:A -> D -> X(1.0) // dist = 2

根据路径最短优先原则,X(1.0) 会被解析使用,也就是说实际用的是 1.0 版本的 X。

但是!这会一些问题:如果 D 依赖用到了 1.5 版本的 X 中才有的一个类,运行项目就会报NoClassDefFoundError错误。如果 D 依赖用到了 1.5 版本的 X 中才有的一个方法,运行项目就会报NoSuchMethodError错误。

        现在知道为什么你的 Maven 项目总是会报NoClassDefFoundErrorNoSuchMethodError错误了吧?

如何解决呢? 我们可以通过exclusion标签手动将 X(1.0) 给排除。

<dependency>......<exclusions><exclusion><artifactId>x</artifactId><groupId>org.apache.x</groupId></exclusion></exclusions>
</dependency>

        一般在解决依赖冲突的时候,都会优先保留版本较高的。这是因为大部分 jar 在升级的时候都会做到向下兼容。

        如果高版本修改了低版本的一些类或者方法的话,这个时候就能直接保留高版本了,而是应该考虑优化上层依赖,比如升级上层依赖的版本。

还是上面的例子:

依赖链路一:A -> B -> C -> X(1.5) // dist = 3
依赖链路二:A -> D -> X(1.0) // dist = 2

        保留了 1.5 版本的 X,但是这个版本的 X 删除了 1.0 版本中的某些类。这个时候,可以考虑升级 D 的版本到一个 X 兼容的版本。

更多消息资讯,请访问昂焱数据。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com