【问题标题】:Maven dependency convergence error (wrong version used)Maven依赖收敛错误(使用了错误的版本)
【发布时间】:2017-06-20 12:13:01
【问题描述】:

我遇到了这个奇怪的问题,我不知道是什么问题。

我有一个结构如下的多模块 java maven 项目:

+ A (parent)
+-+-B
| +--C
| +--D

我在父pom(A)中添加了一个依赖:

  <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>1.8.5</version>
            <exclusions>
                <exclusion>
                    <groupId>com.mchange</groupId>
                    <artifactId>c3p0</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.mchange</groupId>
                    <artifactId>mchange-commons-java</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

注意:A以外的其他模块需要1.8.5版本

在模块 C 和 D 中,必须使用 2.3.0 版本,因此我使用此依赖项覆盖父 pom A 的 1.8.5 版本:

 <dependency>
        <groupId>org.quartz-scheduler</groupId>
        <artifactId>quartz</artifactId>
        <version>2.3.0</version>
        <exclusions>
            <exclusion>
                <groupId>com.mchange</groupId>
                <artifactId>c3p0</artifactId>
            </exclusion>
            <exclusion>
                <groupId>com.mchange</groupId>
                <artifactId>mchange-commons-java</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

我在模块 C 和 D 的 poms 中添加了这个依赖。C 也是 D 的依赖。所以当我尝试构建项目时,我得到以下错误:

[WARNING] Rule 1: org.apache.maven.plugins.enforcer.DependencyConvergence   failed with message:
Failed while enforcing releasability the error(s) are [
Dependency convergence error for org.quartz-scheduler:quartz:1.8.5 paths to dependency are:
+-de.xxx.xxx.xxx:module-D:6.40.1-jat-SNAPSHOT
  +-de.xxx.xxx.xxx:module-C:6.40.1-jat-SNAPSHOT
    +-org.quartz-scheduler:quartz:1.8.5
and
+-de.xxx.xxx.xxx:module-D:6.40.1-jat-SNAPSHOT
  +-org.quartz-scheduler:quartz:2.3.0

所以不知何故,maven 认为模块 C 的石英版本是 1.8.5,但我明确将模块 C 的 pom 中的版本设置为 2.3.0

当我在模块 C 的目录中运行 mvn dependency:tree -Dverbose 时,它​​似乎是正确的: [INFO] +- org.quartz-scheduler:quartz:jar:2.3.0:compile

有人知道吗?

【问题讨论】:

  • 你想使用或覆盖哪个版本,把它放在“dependencyManagement”部分。

标签: java maven dependency-management


【解决方案1】:

模块 A(父模块)的封装类型必须为 pom

一般在父 pom 中声明依赖项是个坏主意,因为它强制所有子模块具有这些特定依赖项,无论它们是否需要。这相当于在每个子模块中声明这些依赖关系。

当模块 C 和 D 开始发挥作用时,您就有了相当于具有冲突版本的重复依赖声明

相反,模块 A 应该使用 &lt;dependencyManagement&gt; 部分来声明依赖版本,而不是强制每个子模块实际依赖它们。

换句话说:

<dependencyManagement>
    <dependencies>
        ...
        <dependency>
           <groupId>org.quartz-scheduler</groupId>
           <artifactId>quartz</artifactId>
           <version>1.8.5</version>
           <exclusions>
               <exclusion>
                  <groupId>com.mchange</groupId>
                  <artifactId>c3p0</artifactId>
               </exclusion>
               <exclusion>
                   <groupId>com.mchange</groupId>
                   <artifactId>mchange-commons-java</artifactId>
               </exclusion>
           </exclusions>
        </dependency>
        ...
    </dependencies>
</dependencyManagement>

模块 C 和 D 中的石英依赖声明将简单地覆盖父 A 中指定的版本。

其他依赖于托管石英库的模块仍然需要显式声明它:

<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
</dependency>

versionexclusions 将从托管依赖声明中提取。

【讨论】:

    【解决方案2】:

    检查模块 C 的依赖层次结构并排除版本 1.8.5(使用像 eclipse 这样的现代 IDE,这应该很容易)。 或者你可以从父 pom 中移除这个依赖,在依赖管理中使用它,在子模块中,指明你想要使用的版本。父pom中的依赖会被所有子继承。

    【讨论】:

      猜你喜欢
      • 2023-03-31
      • 2015-09-19
      • 2021-10-29
      • 2016-08-12
      • 1970-01-01
      • 2016-09-24
      • 2020-04-17
      • 2018-01-05
      • 1970-01-01
      相关资源
      最近更新 更多