Maven依赖性收敛错误(使用了错误的版本)

时间:2017-06-20 12:13:01

标签: java maven dependency-management

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

我有一个多模块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依赖:tree -Dverbose时,它似乎是正确的:     [INFO] + - org.quartz-scheduler:quartz:jar:2.3.0:compile

有人有任何想法吗?

2 个答案:

答案 0 :(得分:0)

Check dependency hierarchy of module C and exclude the version 1.8.5 (with modern IDE like eclipse, this should be easy). Or you may remove this dependency from parent pom, use it in dependency management, and in child module, indicate the version you'd like to use. Dependencies in parent pom will be inherited by all the children.

答案 1 :(得分:0)

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

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

当模块C和D开始发挥作用时,你将拥有相应的重复的依赖声明与冲突的版本

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

换句话说:

<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