有没有办法告诉为什么 Maven 依赖项处于某个版本

Is there a way to tell why a maven dependency is at a certain version

我有一个 spring 引导应用程序(它有一个父 pom)并且通常根据它们的版本管理大量依赖项。

如果我将此添加到我的 pom.xml

<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-java-sdk-dynamodb</artifactId>
</dependency>

并列出它表明版本不是最新的依赖项:

./mvnw dependency:list | grep dynamo
[INFO]    com.amazonaws:aws-java-sdk-dynamodb:jar:1.11.125:compile 

在撰写本文时最新版本是 1.11.838,我当前的版本是几个月 "out of date"。

我的 IDE 通常会很好地向我展示依赖项何时 "managed" 例如由父 pom。但在这种情况下,并不表示情况就是如此。

我的想法是传递依赖性可能正在影响这一点,但我想要一种更靠经验的方法来找出答案。

当然,我可以只向依赖项添加一个显式版本元素,或者为此依赖项添加一个显式依赖项管理元素。但我的问题本质上更具学术性,我想了解为什么 maven 确定这是要解决的正确版本。

理想情况下,我要学习的是"debug"存在哪些工具或流程,例如一个特定的 Maven 插件,可能有助于显示版本的解析方式。

mvn dependency:tree | grep -i dynamo | wc -l 的结果是 1。这(我认为)表明它没有在传递依赖项中多次出现。

Maven 使用 "nearest wins" 启发式来解决依赖关系 (read more about Dependency Mechanism)。

在这里,您可能有两个依赖项,它们依赖于同一个工件 com.amazonaws:aws-java-sdk-dynamodb,但版本不同(1.11.125 和另一个版本)。

当存在冲突时(请参阅我上面提供的指南中的 "Dependency mediation"),Maven 通过从项目的根目录中选择 "nearest" 版本来解决冲突。下面是一个例子:

             +----------------+
             |                |
             |  your project  |
             |                |
             +----+------+----+
                  |      |
            +-----+      +-----+
            |                  |
    +-------v------+    +------v-------+
    | dependency A |    | dependency B |
    +-------+------+    +------+-------+
            |                  |
            |                  |
+-----------v---------+        |
|    com.amazonaws    | +------v-------+
|aws-java-sdk-dynamodb| | dependency C |
|      1.11.125       | +------+-------+
+---------------------+        |
                               |
                     +---------v-----------+
                     |    com.amazonaws    |
                     |aws-java-sdk-dynamodb|
                     |       1.11.838      |
                     +---------------------+

假设您的项目依赖于依赖项 A 和 B,并且这些依赖项传递地依赖于 aws-java-sdk-dynamodb 的两个不同版本(1.11.1251.11.838)。由于版本 1.11.125 是来自根目录的 "nearer",因此选择此版本。这可能就是你的情况。

如果你需要在你自己的代码中使用这个依赖,我建议你明确设置工件的版本,而不是依赖 Maven 选择。

附加信息

从 Maven 2.0.9 开始,如果存在冲突并且没有 "nearest" 工件(在前面的示例中,如果 B 直接依赖于 1.11.838 版本),那么选择的版本取决于 A 是在 pom.xml 中的 B 之前还是之后声明的。如果先声明 A,那么会选择版本 1.11.125

谜语已解决,我使用的 BOM spring-cloud-dependencies:Edgware.SR4 在内部使用 spring-cloud-dependencies-parent:Edgware.SR4,然后使用 spring-cloud-aws-dependencies:1.2.3.RELEASE,最终引用 aws-java-sdk-bom:1.11.125,如图 here 所示。