Maven - 检测同一依赖项的多个版本

2022-09-02 11:57:52

我刚刚经历了一个案例,我的maven项目的两个直接依赖项具有特定传递依赖项的两个不同版本。

在我的特殊情况下,我直接依赖于以下内容:

    <dependency>
        <groupId>org.jclouds.driver</groupId>
        <artifactId>jclouds-sshj</artifactId>
        <version>${jclouds.version}</version>
    </dependency>

    <dependency>
        <groupId>org.mule.modules</groupId>
        <artifactId>mule-module-jersey</artifactId>
        <version>${mule.version}</version>
    </dependency>

这两个依赖项都对 com.sun.jersey:jersey-core 具有(深层)传递依赖项,但每个依赖项具有不同的版本。Maven没有在这方面失败,甚至没有警告(或者如果确实如此,我从未见过它!)这样的事情正在发生......因此,我从未注意到它,直到调试了一个问题,当jclouds依赖项引入的球衣核心版本导致某些东西中断时,发生了这个问题。

是否存在一个maven插件或其他一些工具可以检测到这种深度传递依赖覆盖,并在检测到此类碰撞时至少警告用户(或使maven执行失败)...即使默认的 maven 行为是只选择解析依赖项时出现的第一个版本?


答案 1

使用依赖关系执行器插件。当依赖项未正确收敛时,它将停止生成。

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

答案 2

@Clement P为您提供了一个非常好的答案。但请注意,对于多模块项目,它可能还不够。

执行器插件的分离收敛目标知道如何检测传递依赖关系冲突,但冲突可能会以不同的方式隐藏自身。

假设您有一个多模块项目。根是A,它有2个子模块,B1和B2。

B1 声明对工件 a:b:c: 1.1 的依赖,而 B2 声明对工件 a:b:c: 2.0 的依赖

在这种情况下,如果两个模块都是使用它们的依赖项构建和部署的 - 你将发生冲突,但这是执行器插件不知道如何检测的一种。由于项目A不(不能)依赖于其子模块。

为了克服我们组织中的这个问题,我们使用了relation:list插件并手动分析其输出。

过程的粗略描述:运行此目标的输出是项目层次结构中所有项目的所有可传递依赖项的列表。我们比解析输出,对依赖项进行排序,并仅搜索那些仅因版本ID而异的工件。这需要在CI环境中编写一些脚本,但这是目前获得整体情况的唯一方法。


推荐