如何在Maven中调试工件替换

ysl*_*ysl 2 artifact pom.xml maven transitive-dependency

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

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

以下是dependency:tree在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).
...
Run Code Online (Sandbox Code Playgroud)

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


这里几乎是dependency:treeEclipse 的完整日志,并且选中了调试选项.

t0m*_*ppa 6

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

[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
Run Code Online (Sandbox Code Playgroud)

您可以看到某些传递依赖项删除了javassisthttpcore版本,并且javax.activation版本由一个引发.

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

Maven文档的中介规则如下:

依赖关系中介 - 确定在遇到工件的多个版本时将使用哪个版本的依赖关系.目前,Maven 2.0仅支持使用"最接近的定义",这意味着它将在依赖树中使用与项目最接近的依赖项版本.您可以通过在项目的POM中明确声明它来保证版本.请注意,如果两个依赖关系版本在依赖关系树中处于相同的深度,则直到Maven 2.0.8没有定义哪一个会赢,但是自Maven 2.0.9开始,它就是声明中的顺序:第一个声明获胜.

"最接近的定义"表示所使用的版本将是依赖树中与项目最接近的版本,例如.如果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

但是,您可以做的是自己管理依赖项版本.这称为依赖关系管理,如同相同的文档所述:

依赖关系管理 - 这允许项目作者直接指定在传递依赖关系或未指定版本的依赖关系中遇到工件的版本.在上一节的示例中,依赖项直接添加到A,即使它不是由A直接使用.相反,A可以在其dependencyManagement部分中包含D作为依赖项,并直接控制在何时使用D的哪个版本,或者如果,它被引用.

因此,你可以添加:

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>bar</groupId>
      <artifactId>foo</artifactId>
      <version>1.2.3</version>
    </dependency>
  </dependencies>
</dependencyManagement>
Run Code Online (Sandbox Code Playgroud)

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