如何在Maven中调试工件替换 [英] How to debug artifact replacement in Maven

查看:90
本文介绍了如何在Maven中调试工件替换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个父项目,其中包含十几个子项目,其中一个子项目使用org.apache.httpcomponents:httpclient:jar:4.3.5,具体取决于org.apache.httpcomponents:httpcore:jar:4.3.2.

I have a parent project contains a dozen child projects, one of the child projects use org.apache.httpcomponents:httpclient:jar:4.3.5, which depends on org.apache.httpcomponents:httpcore:jar:4.3.2.

但是,结果httpcore的版本解析为4.2.1,而不是4.3.2.

However, the result version of httpcore is resolved to 4.2.1 instead of 4.3.2.

以下是在Eclipse中选中调试选项的情况下运行dependency:tree时的输出摘要:

The following is an extraction of the output when running dependency:tree with debug option checked in Eclipse:

...
[DEBUG] Using mirror nexus (http://192.168.0.111:8081/nexus/content/groups/public) for apache.snapshots (http://repository.apache.org/snapshots).
[DEBUG]   testArtifact: artifact=org.apache.httpcomponents:httpclient:jar:4.3.5:compile
[DEBUG]   includeArtifact: artifact=org.apache.httpcomponents:httpclient:jar:4.3.5:compile
[DEBUG]   startProcessChildren: artifact=org.apache.httpcomponents:httpclient:jar:4.3.5:compile
[DEBUG]     manageArtifactVersion: artifact=org.apache.httpcomponents:httpcore:jar:4.3.2:compile, replacement=org.apache.httpcomponents:httpcore:jar:4.2.1
[DEBUG] Using mirror nexus (http://192.168.0.111:8081/nexus/content/groups/public) for apache.snapshots (http://repository.apache.org/snapshots).
...

它仅显示replacement=org.apache.httpcomponents:httpcore:jar:4.2.1,但是它没有说明更换原因.父项目的pom.xml使用了很多依赖关系,即使我可以尝试一一删除这些依赖关系并检查结果,也将非常耗时.有没有更有效的方法来调试工件替换?

It just shows replacement=org.apache.httpcomponents:httpcore:jar:4.2.1, but it tells nothing about the reason of the replacement. The parent project's pom.xml uses quite a lot dependencies and even though I could try to remove those dependencies one by one and check the result, it would be quite time consuming. Is there any more effective way to debug the artifact replacement?

此处几乎是Eclipse中dependency:tree的完整日志,调试选项已选中.

Here is almost the full log of the dependency:tree from Eclipse with debug option checked.

推荐答案

从日志中,您可以找到以下行:

From your log, you can find the lines:

[DEBUG] com.company.xyz:xyz-integration-lib:jar:0.0.1-SNAPSHOT
[DEBUG]    com.company.xyz:xyz-utils:jar:0.0.1-SNAPSHOT:compile
[DEBUG]       commons-codec:commons-codec:jar:1.8:compile
[DEBUG]    javax.mail:mail:jar:1.4:provided
[DEBUG]       javax.activation:activation:jar:1.1.1:provided (version managed from 1.1 by org.jboss.spec:jboss-javaee-6.0:3.0.2.Final)
[DEBUG]    org.apache.commons:commons-lang3:jar:3.3.2:compile
[DEBUG]    junit:junit:jar:4.8.2:test
[DEBUG]    com.thoughtworks.xstream:xstream:jar:1.4.7:compile
[DEBUG]       xmlpull:xmlpull:jar:1.1.3.1:compile
[DEBUG]       xpp3:xpp3_min:jar:1.1.4c:compile
[DEBUG]    joda-time:joda-time:jar:2.4:compile
[DEBUG]    org.assertj:assertj-joda-time:jar:1.1.0:test
[DEBUG]       org.assertj:assertj-core:jar:1.3.0:test
[DEBUG]    org.apache.httpcomponents:httpclient:jar:4.3.5:compile
[DEBUG]       org.apache.httpcomponents:httpcore:jar:4.2.1:compile (version managed from 4.3.2 by org.jboss.as:jboss-as-parent:7.2.0.Final)
[DEBUG]    commons-logging:commons-logging:jar:1.1.3:compile
[DEBUG]    org.slf4j:slf4j-api:jar:1.7.7:compile
[DEBUG]    org.slf4j:slf4j-log4j12:jar:1.7.7:compile
[DEBUG]       log4j:log4j:jar:1.2.17:compile
[DEBUG]    org.mockito:mockito-all:jar:1.9.5:test
[DEBUG]    org.powermock:powermock-module-junit4:jar:1.5.5:test
[DEBUG]       org.powermock:powermock-module-junit4-common:jar:1.5.5:test
[DEBUG]          org.powermock:powermock-core:jar:1.5.5:test
[DEBUG]             org.javassist:javassist:jar:3.18.1-GA:test (version managed from 3.18.2-GA by org.springframework.boot:spring-boot-dependencies:1.1.4.RELEASE)
[DEBUG]          org.powermock:powermock-reflect:jar:1.5.5:test
[DEBUG]             org.objenesis:objenesis:jar:2.1:test
[DEBUG]    org.powermock:powermock-api-mockito:jar:1.5.5:test
[DEBUG]       org.powermock:powermock-api-support:jar:1.5.5:test

在这里您可以看到javassisthttpcore版本由于某些传递依赖项而被删除,而javax.activation版本被提升了一个.

Where you can see that the javassist and httpcore versions are dropped by certain transitive dependencies and javax.activation version is raised by one.

当您的项目依赖项中有多个依赖于同一库并且已定义该库的不同版本的依赖项时,就会发生这种情况.这可能很烦人,因为通常您无法更改父POM或其依赖项如何影响可传递依赖项的版本.

This happens when more than one of your project dependencies are depending on the same library and have defined dependencies to different versions of that library. This can be annoying, since generally you cannot change how the parent POM or its dependencies are affecting the versions of your transitive dependencies.

来自 Maven文档的中介规则如下如下:

The mediation rules from Maven docs are as follows:

依赖关系中介-这确定了哪个版本的依赖关系 遇到工件的多个版本时将使用. 当前,Maven 2.0仅支持使用最近定义" 这意味着它将使用最接近的依赖项的版本 您的项目在依赖树中.您可以随时保证 版本号,方法是在项目的POM中明确声明它.请注意,如果 在依赖关系树中,两个依赖关系版本处于相同的深度, 在Maven 2.0.8之前,尚不确定哪一个会获胜,但由于 Maven 2.0.9是最重要的是声明中的顺序:第一个 宣告胜利.

Dependency mediation - this determines what version of a dependency will be used when multiple versions of an artifact are encountered. Currently, Maven 2.0 only supports using the "nearest definition" which means that it will use the version of the closest dependency to your project in the tree of dependencies. You can always guarantee a version by declaring it explicitly in your project's POM. Note that if two dependency versions are at the same depth in the dependency tree, until Maven 2.0.8 it was not defined which one would win, but since Maven 2.0.9 it's the order in the declaration that counts: the first declaration wins.

最近的定义"表示所使用的版本将是依赖树中最接近您项目的版本.如果 A,B和C的依赖关系定义为A-> B-> C-> D 2.0和A -> E-> D 1.0,则在构建A时将使用D 1.0,因为从A到D到E的路径更短.您可以显式添加一个 依赖于A中的D 2.0强制使用D 2.0

"nearest definition" means that the version used will be the closest one to your project in the tree of dependencies, eg. if dependencies for A, B, and C are defined as A -> B -> C -> D 2.0 and A -> E -> D 1.0, then D 1.0 will be used when building A because the path from A to D through E is shorter. You could explicitly add a dependency to D 2.0 in A to force the use of D 2.0

但是,您可以做的是自己管理依赖项版本.这被称为依赖性管理,正如同一份文档所述:

However what you can do is manage the dependency versions yourself. This is called dependency management and as stated by the same docs:

依赖管理-这使项目作者可以直接 指定遇到工件时要使用的工件的版本 在传递依赖项中或在没有版本的依赖项中 被指定.在上一节的示例中,依赖项 被直接添加到A,即使A没有直接使用它也是如此. 相反,A可以将D作为依赖项包含在其dependencyManagement中 部分,并直接控制何时或是否使用D版本 它曾经被引用过.

Dependency management - this allows project authors to directly specify the versions of artifacts to be used when they are encountered in transitive dependencies or in dependencies where no version has been specified. In the example in the preceding section a dependency was directly added to A even though it is not directly used by A. Instead, A can include D as a dependency in its dependencyManagement section and directly control which version of D is used when, or if, it is ever referenced.

因此,您只需添加:

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>bar</groupId>
      <artifactId>foo</artifactId>
      <version>1.2.3</version>
    </dependency>
  </dependencies>
</dependencyManagement>

进入您自己的POM,它将始终覆盖通过依赖关系中介为传递依赖定义的任何版本.

into your own POM and this will always override whatever version are being defined for your transitive dependencies through dependency mediation.

这篇关于如何在Maven中调试工件替换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆