You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

为何多模块Maven项目依赖冲突时会使用旧版本?

Maven依赖冲突:为啥testA选了commons-lang3 3.1而非3.4?

嘿,这个问题我之前踩过坑,核心是Maven的**依赖调解(Dependency Mediation)**规则在搞事情,咱们一步步拆解明白:

1. 为啥你的testA用了3.1版本?

很多人误以为Maven会自动选版本号最高的依赖,但其实它的默认优先级是路径最短优先(官方叫「Nearest Definition」),不是版本优先。咱们梳理下你的依赖链:

  • commons-lang3:3.1的路径:testA → vaadin-client-compiler → commons-lang3:3.1(只隔了1层依赖,路径长度2)
  • commons-lang3:3.4的路径:testA → testB → commons-lang3:3.4(隔了2层依赖,路径长度3)

因为3.1的路径更短,Maven就默认挑了它,这就是你看到不符合预期结果的原因。要是两个依赖路径长度一样,Maven才会看你在pom里的声明顺序,先写的那个依赖带的版本会被选中。

2. 为啥在testB版本里加[]能解决问题?

你说的在testB版本里加[],应该是指用精确版本范围声明(比如<version>[3.4]</version>),本质是你通过这种方式告诉Maven:「不管别的规则,就用3.4这个版本」。版本范围[3.4]表示必须匹配这个精确版本,Maven解析时会优先遵循这个明确要求,直接覆盖了原本的路径优先规则。

3. 有没有不用强制,让Maven自动选3.4的办法?

Maven本身没「自动选最高版本」的默认规则,但有几个更优雅的方式能让3.4被选中:

  • 在testA里直接依赖commons-lang3:3.4:这样它的路径长度就变成1(testA → commons-lang3:3.4),比3.1的路径更短,Maven自然会选这个版本。
  • 用父pom的<dependencyManagement>统一版本:在父项目的<dependencyManagement>块里声明commons-lang3的版本为3.4,所有子模块都会自动遵循这个版本,不管依赖链里的其他版本声明。
  • 排除vaadin-client-compiler里的commons-lang3:在testA对vaadin-client-compiler的依赖里加<exclusions>,把它带的3.1版本排除掉,这样Maven就只能用testB带的3.4版本了。

内容的提问来源于stack exchange,提问作者Black Trans Woman

火山引擎 最新活动