同一个工件使用同一个依赖的不同版本

Same artifact uses different versions of same dependency

我正在使用 maven enforcer 插件,但我发现了这种依赖收敛的奇怪情况:

Dependency convergence error for commons-collections:commons-collections:3.2.1 paths to dependency are:
+-ProjectA:B:0.1
  +-commons-validator:commons-validator:1.6
    +-commons-beanutils:commons-beanutils:1.9.2
      +-commons-collections:commons-collections:3.2.1
and
+-ProjectA:B:0.1
  +-commons-validator:commons-validator:1.6
    +-commons-collections:commons-collections:3.2.2

这是依赖声明:

<dependency>
    <groupId>commons-validator</groupId>
    <artifactId>commons-validator</artifactId>
    <version>1.6</version>
</dependency>

你可以看到同一个工件使用同一个依赖的不同版本。 这怎么会发生?抑制警告的唯一方法是将该依赖项的最新版本作为直接依赖项包含在我的 pom 中。

我是不是漏掉了什么?

从依赖树中您可以看到 commons-validator:commons-validator:1.6 直接依赖于 commons-collections:commons-collections:3.2.2,但也有对 commons-collections:commons-collections:3.2.1 的传递依赖。这没什么不寻常的。

要解决此问题,您需要选择一个版本。只需遵循 khmarbaise 的建议并在 POM 的 <dependencyManagement> 部分添加一个条目。

最重要的是,同一工件不会使用同一依赖项的不同版本。

+-ProjectA:B:0.1
  +-commons-validator:commons-validator:1.6
    +-commons-beanutils:commons-beanutils:1.9.2
      +-commons-collections:commons-collections:3.2.1
and
+-ProjectA:B:0.1
  +-commons-validator:commons-validator:1.6
    +-commons-collections:commons-collections:3.2.2

Dependency commons-validator:commons-validator:1.6 直接使用 commons-collections:commons-collections:3.2.2 并传递 commons-collections:commons-collections:3.2.1 (另一个依赖的依赖)。 Maven 的依赖调解将基于最近最新原则解决此冲突。 看看这些:
[1] Dependency Mechanism
[2] Dependency Mediation and Conflict Resolution

maven-enforcer-plugin`s dependencyConvergence 规则工作正常。 正如 documentation 所说:

This rule requires that dependency version numbers converge. If a project has two dependencies, A and B, both depending on the same artifact, C, this rule will fail the build if A depends on a different version of C then the version of C depended on by B.

因为 commons-validator (A) 和 commons-beanutils (B) 取决于 commons-collections (C) 并且这些依赖项具有不同的版本,所以这种行为是完全合理的。

你决定你想做什么。

继续使用 dependencyConvergence 规则并解决此错误

在这种情况下,只需在 <dependencyManagement> 部分定义 commons-collectionscommons-loggingcommons-validator,并将这些依赖项作为托管依赖项放入您的项目中。

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>commons-validator</groupId>
                <artifactId>commons-validator</artifactId>
                <version>1.6</version>
            </dependency>
            <dependency>
                <groupId>commons-collections</groupId>
                <artifactId>commons-collections</artifactId>
                <version>3.2.2</version>
            </dependency>
            <dependency>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
                <version>1.2</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>commons-validator</groupId>
            <artifactId>commons-validator</artifactId>
        </dependency>
        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
        </dependency>
    </dependencies>

我认为它需要大量的工作量,一段时间后您的项目模型将无法维护。另一方面,Dependency Mediation 规则解决了这个问题。

使用其他规则,例如requireUpperBoundDeps

此规则旨在调查构建期间解析的依赖项是否低于所有传递依赖项声明。例如。如果您的项目依赖 commons-collections:3.0commons-validator 需要更新版本 commons-collections:3.2.2

,它将失败
    <dependencies>
        <dependency>
            <groupId>commons-validator</groupId>
            <artifactId>commons-validator</artifactId>
            <version>1.6</version>
        </dependency>
        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
            <version>3.0</version>
        </dependency>
    </dependencies>

忘掉执行者,相信依赖调解

几乎在所有情况下,这是正确的决定,因为 Dependency Mediation 工作正常。