【问题标题】:Is there a way to tell why a maven dependency is at a certain version有没有办法说明为什么 Maven 依赖项处于某个版本
【发布时间】:2018-08-09 17:02:16
【问题描述】:

我有一个 spring boot 应用程序(它有一个父 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,我当前的版本已经“过时”了好几个月。

我的 IDE 通常会很好地向我展示何时“管理”依赖项,例如由父 pom。但在这种情况下,它并不表明情况就是这样。

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

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

理想情况下,我想了解的是存在哪些工具或流程来“调试”这个,例如一个特定的 maven 插件,它可能有助于显示一个版本是如何被解析的。

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

【问题讨论】:

  • 你用的是哪个版本的spring-boot?
  • 在这种情况下1.5.15.RELEASE。如果我在 spring boot 2.0.4.RELEASE 中做同样的事情,我会得到发电机依赖 1.11.336 - 但仍然不是最新的。

标签: maven maven-2 maven-3


【解决方案1】:

Maven 使用“最近胜出”启发式来解决依赖关系 (read more about Dependency Mechanism)。

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

当发生冲突时(请参阅我上面提供的指南中的“依赖调解”),Maven 通过从项目的根目录中选择“最近的”版本来解决它。下面是一个例子:

             +----------------+
             |                |
             |  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 离根“更近”,因此选择此版本。这可能就是您的情况。

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

其他信息

从 Maven 2.0.9 开始,如果存在冲突并且没有“最近”工件(在前面的示例中,如果 B 直接依赖于 1.11.838 版本),那么选择的版本取决于 A 是否为在您的pom.xml 中在B 之前或之后声明。如果首先声明 A,则将选择版本 1.11.125

【讨论】:

  • 投票支持综合信息,但是如果我运行这个命令:mvn dependency:tree | grep -i dynamo | wc -l,结果是1。除非我误解了这棵树向我展示的内容——如果存在某种冲突的传递依赖,发电机不会在树中出现两次,而不是一次?
  • @DavidGoate 如果您运行mvn dependency:tree -Dverbose,Maven 将向您显示所有依赖项,并带有类似omitted for conflict with x.x.x 的消息,表示依赖项因版本冲突而被驱逐。因此,您应该看到哪些工件取决于 aws-java-sdk-dynamodb,以及不同的版本。
  • 感谢您的推荐,这确实很有趣,并向我展示了对我来说是新的信息。命令mvn dependency:tree -Dverbose | grep -i dynamo 只显示[INFO] +- com.amazonaws:aws-java-sdk-dynamodb:jar:1.11.125:compile,所以没有关于重复/冲突的消息(列表中的其他人有但不是发电机)再次感谢您的尝试,但这对我来说似乎仍然没有解决这个特定的依赖关系是如何产生的解决到那个版本。
  • 嗯,这很奇怪......您能否在您的问题中发布您的 POM,或者至少重现导致相同情况的最小 POM?
  • 感谢您的帮助,非常有价值,让我发现了根本问题。
【解决方案2】:

谜题解决了,我使用的是 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

【讨论】:

    猜你喜欢
    • 2015-06-11
    • 2011-06-10
    • 2014-12-14
    • 2021-02-07
    • 1970-01-01
    • 2012-01-11
    • 2021-12-18
    • 2018-04-16
    相关资源
    最近更新 更多