【问题标题】:How does Maven Choose the Version of a Transitive Dependency when Two or More Versions of that Dependency Exist in the Dependency Tree?当依赖关系树中存在两个或多个依赖关系版本时,Maven 如何选择传递依赖关系的版本?
【发布时间】:2018-10-20 02:19:19
【问题描述】:

我有一个项目,它依赖于我维护的一个名为 microservices-common 的库。 microservices-common 库又依赖于commons-codec:1.11。但是,当我尝试在我的项目中使用 microservices-common 时,commons-codec:1.10 最终出现在我的类路径中,并且我的代码无法编译,因为 microservices-common 正在尝试使用添加到 commons-codec:1.11org.apache.commons.codec.digest.DigestUtils 构造函数,但在 commons-codec:1.10 中不存在。

这里是 microservices-common 依赖树的相关部分:

[INFO] com.myproject:microservice-common:jar:1.0-SNAPSHOT
[INFO] +- commons-codec:commons-codec:jar:1.11:compile
[INFO] +- org.apache.httpcomponents:httpclient:jar:4.5.5:compile
[INFO] |  \- (commons-codec:commons-codec:jar:1.10:compile - omitted for conflict with 1.11)
[INFO] \- com.myproject:restful:jar:4.1.5-SNAPSHOT:compile
[INFO]    +- com.myproject:restful-common:jar:4.1.5-SNAPSHOT:compile
[INFO]    |  \- (commons-codec:commons-codec:jar:1.8:compile - omitted for conflict with 1.11)
[INFO]    \- (commons-codec:commons-codec:jar:1.8:compile - omitted for conflict with 1.11)

如果我正确读取了树,其他版本的 commons-codec 依赖项,包括 v1.8 和 v1.10 将从类路径中省略,而支持 v1.11,这正是我想要的。

但是,如果我从依赖于 microservices-common 的项目的角度来拉取依赖树,它看起来像这样:

[INFO] com.myproject:microservice:jar:1.0-SNAPSHOT
[INFO] +- org.apache.httpcomponents:httpasyncclient:jar:4.1.3:compile
[INFO] |  \- org.apache.httpcomponents:httpclient:jar:4.5.3:compile
[INFO] |     \- (commons-codec:commons-codec:jar:1.10:compile - version managed from 1.11; omitted for duplicate)
[INFO] \- com.myproject:microservice-common:jar:1.0-SNAPSHOT:compile
[INFO]    +- commons-codec:commons-codec:jar:1.10:compile
[INFO]    \- com.myproject:restful:jar:4.1.5-SNAPSHOT:compile
[INFO]       +- com.myproject:restful-common:jar:4.1.5-SNAPSHOT:compile
[INFO]       |  \- (commons-codec:commons-codec:jar:1.10:compile - version managed from 1.8; omitted for duplicate)
[INFO]       \- (commons-codec:commons-codec:jar:1.10:compile - version managed from 1.8; omitted for duplicate)

在这棵树中,我看到消息“从 1.x 管理的版本;重复省略”。我不确定这究竟是什么意思,更令人担忧的是,第 6 行显示 commons-codec:1.10 是我的类路径上的最终结果,而不是我真正想要的 v1.11。

需要注意的是,com.myproject:microservice-common:jar:1.0-SNAPSHOTpom.xml 声明了 commons-codec:1.11 依赖项,因此 commons-codec:1.10 可能来自的唯一位置是 org.apache.httpcomponents:httpclient:jar:4.1.3 或 @ 987654335@ (另一个由于遗留原因我无法摆脱的公共库),但我不清楚为什么选择传递依赖项的该版本以包含在我的微服务公共库声明的版本之上。

谁能解释当依赖树中存在同一个库的多个版本时依赖选择是如何工作的,以及为什么 microservices-common 在隔离构建时似乎选择了传递依赖的正确版本,但我的微服务项目选择了不同的我构建它时的版本?

【问题讨论】:

    标签: maven dependencies dependency-management


    【解决方案1】:

    Maven 选择依赖关系树中 最近 的依赖关系版本。这在Maven documentation中有很好的解释:

    “最接近的定义”表示使用的版本将是最接近的 一个到您的项目在依赖关系树中,例如。如果依赖 对于 A、B 和 C,定义为 A -> B -> C -> D 2.0 和 A -> E -> D 1.0,那么在构建A时将使用D 1.0,因为从A到D通过E的路径更短。

    如果依赖项在同一级别多次出现,则第一个声明获胜(自 Maven 2.0.9 起)。

    确保使用所需版本的 commons-codec 的最佳且已建立的方法是在您的“微服务”pom 中声明 dependencyManagement(直接在 project 元素下):

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>commons-codec</groupId>
                <artifactId>commons-codec</artifactId>
                <version>1.11</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
    

    另外,请确保您运行的是最新版本的 Maven(推荐 3.5)。

    【讨论】:

      猜你喜欢
      • 2010-09-18
      • 2013-11-05
      • 2014-07-12
      • 2015-12-28
      • 1970-01-01
      • 2019-07-04
      • 2015-07-19
      • 2019-12-29
      • 1970-01-01
      相关资源
      最近更新 更多