为什么Maven选择版本1.0.b2超过1.3.03

时间:2014-04-24 11:57:01

标签: java maven xerces

我有一个依赖于HTTP BUilder的项目,这给了我后续的依赖树:

[INFO] +- org.codehaus.groovy.modules.http-builder:http-builder:jar:0.5.1:compile
[INFO] |  +- org.apache.httpcomponents:httpclient:jar:4.3.2:compile
[INFO] |  |  \- commons-codec:commons-codec:jar:1.6:compile
[INFO] |  +- net.sf.json-lib:json-lib:jar:jdk15:2.3:compile
[INFO] |  |  +- commons-beanutils:commons-beanutils:jar:1.8.0:compile
[INFO] |  |  +- commons-collections:commons-collections:jar:3.2.1:compile
[INFO] |  |  +- commons-lang:commons-lang:jar:2.4:compile
[INFO] |  |  \- net.sf.ezmorph:ezmorph:jar:1.0.6:compile
[INFO] |  +- net.sourceforge.nekohtml:nekohtml:jar:1.9.9:compile
[INFO] |  |  \- xerces:xercesImpl:jar:2.8.1:compile
[INFO] |  |     \- xml-apis:xml-apis:jar:1.3.03:compile
[INFO] |  \- xml-resolver:xml-resolver:jar:1.2:compile

添加hibernate-entitymanager后,xml-apis:aml-apis的版本发生了变化。突然间,Maven更喜欢使用版本1.0b2,它是dom4j的传递依赖:

[INFO] +- org.hibernate:hibernate-entitymanager:jar:4.3.1.Final:compile
[INFO] |  +- org.jboss.logging:jboss-logging:jar:3.1.3.GA:compile
[INFO] |  +- org.jboss.logging:jboss-logging-annotations:jar:1.2.0.Beta1:compile
[INFO] |  +- org.hibernate:hibernate-core:jar:4.3.1.Final:compile
[INFO] |  |  +- antlr:antlr:jar:2.7.7:compile
[INFO] |  |  \- org.jboss:jandex:jar:1.1.0.Final:compile
[INFO] |  +- dom4j:dom4j:jar:1.6.1:compile
[INFO] |  |  \- xml-apis:xml-apis:jar:1.0.b2:compile

由于这个原因,我现在在运行时遇到以下异常:

java.lang.IncompatibleClassChangeError: 
Class org.apache.xerces.parsers.AbstractSAXParser$LocatorProxy 
does not implement the requested interface org.xml.sax.Locator

我知道我可以通过在我的pom.xml中手动添加具有良好版本号的依赖项来修复它,但我想知道为什么需要这样做:

    <dependency>
        <groupId>xml-apis</groupId>
        <artifactId>xml-apis</artifactId>
        <version>1.3.03</version>
    </dependency>

2 个答案:

答案 0 :(得分:9)

默认情况下,当在依赖关系树中找到相同的依赖关系时,Maven会使用最接近根的依赖关系。

在您的情况下,这意味着

 org.hibernate:hibernate-entitymanager:jar:4.3.1.Final:compile
    \- dom4j:dom4j:jar:1.6.1:compile
       \- xml-apis:xml-apis:jar:1.0.b2:compile 

Vs的

 org.codehaus.groovy.modules.http-builder:http-builder:jar:0.5.1:compile
    \- net.sourceforge.nekohtml:nekohtml:jar:1.9.9:compile
       \- xerces:xercesImpl:jar:2.8.1:compile
          \- xml-apis:xml-apis:jar:1.3.03:compile

或者换句话说 3级深度 vs 4级深度,以便1.0.b2获胜。

要解决此问题,请从xml-apis的依赖项中排除hibernate-entitymanager或明确声明xml-apis的依赖项(尽管您可能需要对此进行一些操作,Xerces及其依赖项可能是一个噩梦,以获得对齐的版本)。

答案 1 :(得分:1)

这是必要的,因为Maven无法知道它应该选择哪个版本,因此Maven使用最近赢策略来选择使用哪个版本。最近赢的策略是documented in Maven documentation

在你提供版本1.0.b2的依赖tee中,显然是最接近的,所以行为就像设计的一样。

您可能希望查看前面已经讨论过的this thread(我无法确定该线程是否与此相关)