当前位置: 首页 > news >正文

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 兼容的版本。

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

http://www.lryc.cn/news/397043.html

相关文章:

  • demon drone 200无人机标定流程
  • 案例开发-日程管理-第一期
  • 【Java 注解,自定义注解,元注解,注解本质,注解解析】
  • 染色法判定二分图
  • 自动气象站的主要功能优势
  • Java中实现二维数组(矩阵)的转置
  • Prometheus+Grafana主机运行数据
  • GraphQL在Postman中:释放API查询的强大潜能
  • 大语言模型里的微调vs RAG vs 模板提示词
  • 网络编程:常用网络测试工具
  • mov视频怎么改成mp4?把mov改成MP4的四个方法
  • 力扣1472.设计浏览器历史记录
  • 准大一新生开学千万要带证件照用途大揭秘
  • QImage显示图片像素
  • uniapp使用高德地图(公众号+h5)
  • 深度学习与浅层学习:技术变革下的竞争态势
  • LeetCode 219. 存在重复元素 II
  • 【目标检测】使用自己的数据集训练并预测yolov8模型
  • 应用监控SkyWalking调研
  • Selenium使用注意事项:
  • 小程序需要进行软件测试吗?小程序测试有哪些测试内容?
  • 一文读懂企业租用GPU的注意事项!
  • Linux运维:mysql主从复制原理及实验
  • 022-GeoGebra中级篇-几何对象之直线与坐标轴
  • node js安装、配置(Windows版)
  • go语言day08 泛型 自定义错误处理 go关键字:协程
  • MySql性能调优01-[数据结构和索引]
  • 【算法入门-栈】逆波兰表达式求值
  • 【史上最全面ESP32教程】http通信
  • *算法训练(leetcode)第二十七天 | 56. 合并区间、738. 单调递增的数字、968. 监控二叉树