问题描述
我有一个父项目,其中包含十几个子项目,其中一个子项目使用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
在这里您可以看到javassist
和httpcore
版本由于某些传递依赖项而被删除,而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:
最近的定义"表示所使用的版本将是依赖树中最接近您项目的版本.如果 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:
因此,您只需添加:
<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中调试工件替换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!