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

Bar*_*lly 4 java dependency-management maven

我正在开发一个大型 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
Run Code Online (Sandbox Code Playgroud)

现在单元测试将在存在 的情况下module-a进行练习,而将在存在 的情况下进行练习。library-alibrary-c:v1module-blibrary-blibrary-c:v2

问题在于,部署时module-amodule-b需要一起生活在同一个类路径上,但无论打包时选择module-c哪个版本,至少有一个库组合尚未经过单元测试!library-cmodule-c

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

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

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

这个问题有多严重?除了获得令人难以置信的测试覆盖率外,在实践中,我还看到NoSuchMethodError由于部署了错误的版本而导致运行时 JVM 被终止。我希望至少在测试时看到这些。

gly*_*ing 5

看起来这有两个方面:

  1. 您需要坚持依赖项的单一版本,无论是显式声明还是传递获取

你可以<dependencyManagement/>在这里使用。例如,在顶级 pom.xml 中,您可以固定以下版本library-c

<dependencyManagement>
 <dependencies>
    <dependency>
        <groupId>your.group.id</groupId>
        <artifactId>library-c</artifactId>
        <version>2</version>
    <dependency>
  <dependencies>
<dependencyManagement>
Run Code Online (Sandbox Code Playgroud)

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

<dependencies>
  <dependency>
    <groupId>your.group.id</groupId>
    <artifactId>library-c</artifactId>
  <dependency>
<dependencies>
Run Code Online (Sandbox Code Playgroud)

通过在父模块中声明此依赖项,dependencyManagement您将坚持使用在父模块中声明的版本的两个子模块。

  1. 您希望保护自己免受将来发生的不愉快的依赖项添加的影响

您可以在此处使用Maven Enforcer 插件,特别是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>
Run Code Online (Sandbox Code Playgroud)

如果发现非收敛依赖性,强制执行器可以配置为失败或发出警告。