6

我在父 pom 的导入的 dependencyManagement 部分中指定了一个库版本。我确认我的有效 pom 只有一次出现这种依赖。它在依赖管理部分:

<dependencyManagement>
    <dependency>
        <groupId>org.javassist</groupId>
        <artifactId>javassist</artifactId>
        <version>[3.18.1-GA]</version>
    </dependency>
</dependencyManagement>

这应该根据它覆盖传递依赖项的版本。安装(并重新安装依赖项以匹配版本边界)后,org.apache.maven.plugins:maven-dependency-plugin:2.8:tree 打印:

org.javassist:javassist:jar:3.18.1-GA:compile (version selected from constraint [3.18.1-GA,3.18.1-GA])

但是(最初,没有重新安装依赖项)enforcer 抱怨错误的版本:

[WARNING] Rule 1: org.apache.maven.plugins.enforcer.DependencyConvergence failed with message:
Failed while enforcing releasability the error(s) are [
Dependency convergence error for org.javassist:javassist:3.18.2-GA paths to dependency are:
...

并表明第一个传递依赖使用

org.javassist:javassist:3.18.2-GA

这来自依赖,而依赖又依赖于:

<dependencies>
    <dependency>
        <groupId>org.javassist</groupId>
        <artifactId>javassist</artifactId>
        <version>3.18.2-GA</version>
    </dependency>
</dependencies>

和其他用途

org.javassist:javassist:3.18.1-GA

为什么执行器与依赖树不一致?有什么问题?如果我使用版本限制,它们是否会受到尊重,我可以跳过为此目的使用强制执行器吗?

此外,向相关项目模块添加依赖项不会改变任何内容。

4

1 回答 1

6

Tl;dr :dependencyManagement覆盖传递依赖的版本

这个答案的所有功劳归功于我偶然发现的 Andy Dennie 的博客文章:
https ://www.fizz-buzz.com/blog/2012/08/02/maven-enforcer-plugin-vs-dependencymanagement

dependencyManagement做两件事——一件众所周知,另一件很少被提及。

  1. 为子模块/子项目中的依赖项设置默认版本
  2. 覆盖传递依赖的版本

因此,enforcer 插件不会忽略dependencyManagement. 但是无法识别差异,因为传递依赖的版本在它开始工作之前就被改变了。Andy Denny 在他的博客上对如何进行有一个很好的建议:

  1. 我没有将依赖项放在我的顶级 POM 的 dependencyManagement 部分。当我遇到不匹配时,我想收到 maven-enforcer-plugin 的提醒。相反,我使用版本属性,如上面我的方法 #1 中所述。
  2. 当 maven-enforcer-plugin 通知我存在差异时,我会尝试查看是否可以让所涉及的工件使用相同版本的发散依赖项。如果涉及的所有依赖项都在我自己的工件中,我会尝试让它们在相同版本的依赖项上对齐。如果有些工件是我的,有些来自第 3 方,我会尝试将我的依赖项与第 3 方对齐,和/或查找具有相互对齐的依赖项版本的第 3 方工件的其他版本,以及我的代码。
  3. 如果在执行上述操作后,我仍然有无法解决的差异,我选择我认为有问题的工件的“最合适”版本,并在 maven-enforcer-plugin 报告问题的项目 POM 的 dependencyManagement 部分中指定它(不是在我的顶级 POM 中)。我在该 POM 中的依赖项声明中添加了一条注释,指出了问题和解决方法,这样将来,如果我升级到更新版本的依赖项,我将看到该注释并重新审视差异是否可能得到解决。

这里的权衡是你有一个有效的执行器插件,可以帮助你解决依赖问题,但必须手动完成更多工作。

于 2014-12-23T17:33:13.777 回答