如何跨多 pom Maven 项目固定传递依赖版本

How to pin transitive dependency versions across multi-pom Maven project

我正在开发一个大型 Java 代码库,该代码库分为多个模块,每个模块都有一个单独的 pom.xml,所有模块都由顶级 pom.xml.

我目前正在引入几个库依赖项。可传递的依赖集很大,幸运的是,不同模块的依赖版本存在冲突。

这是我的情况的简化:

project/pom.xml
       /module-a/pom.xml # references library-a, depends on library-c:v1
       /module-b/pom.xml # references library-b, depends on library-c:v2
       /module-c/pom.xml # references module-a and module-b

现在 module-a 的单元测试将在 library-c:v1 存在的情况下执行 library-a,而 module-b 将在 library-b 存在的情况下执行 library-b =16=].

问题在于部署 module-cmodule-amodule-b 需要在同一个类路径上共存,但是当 library-c 选择哪个版本时 module-c被打包,至少有一个组合库没有经过单元测试!

我想以某种方式将 library-c 的版本固定在父 pom 级别,而不是在每个传递依赖于 library-c 的模块中重复我自己;理想情况下,它会以这样一种方式添加,表明它是允许消失的传递依赖,如果 library-alibrary-b 不再依赖它。

我想保证只选择了一个版本 整个项目中的每一个传递依赖都源于这个父 pom,如果这不是真的,我希望构建崩溃。我写了一个工具来解析 mvn dependency:tree 的输出(将树的叶子变成从叶子到根的路径森林,然后用依赖路径找到所有不同版本的叶子)所以我可以看到问题,但是如果没有明确解决每个冲突的传递依赖关系并用冗余声明膨胀 poms,这似乎没有成果。万不得已,我自然会这么做。

用 Maven 处理这个传递依赖冲突问题的最佳方法是什么?

这个问题有多严重?除了获得令人信服的测试覆盖率之外,在实践中,我看到 JVM 在运行时因部署错误的版本而被杀死 NoSuchMethodError。我宁愿至少在测试时看到这些。

看起来这有两个方面:

  1. You need to insist on a single version of a dependency, whether it is declared explicitly or acquired transitively

你可以在这里使用<dependencyManagement/>。例如在顶层 pom.xml 你可以固定 library-c:

的版本
<dependencyManagement>
 <dependencies>
    <dependency>
        <groupId>your.group.id</groupId>
        <artifactId>library-c</artifactId>
        <version>2</version>
    <dependency>
  <dependencies>
<dependencyManagement>

然后在 library-alibrary-b 中声明对 library-c 的依赖,如下所示:

<dependencies>
  <dependency>
    <groupId>your.group.id</groupId>
    <artifactId>library-c</artifactId>
  <dependency>
<dependencies>

通过在父模块 dependencyManagement 中声明此依赖关系,您坚持要求两个子模块都使用在父模块中声明的版本。

  1. You want to protect yourself from unhappy dependency additions occurring in future

您可以使用 Maven Enforcer plugin here, specifically the dependencyConvergence 规则。例如:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-enforcer-plugin</artifactId>
    <version>3.0.0-M1</version>
    <executions>
      <execution>
        <id>enforce</id>
        <configuration>
          <rules>
            <dependencyConvergence/>
          </rules>
        </configuration>
        <goals>
          <goal>enforce</goal>
        </goals>
      </execution>
    </executions>
</plugin>

强制执行器可以配置为在发现非收敛依赖项时失败或发出警告。