【问题标题】:Why does Maven choose version 1.0.b2 over 1.3.03为什么 Maven 选择版本 1.0.b2 而不是 1.3.03
【发布时间】:2014-06-09 16:45:15
【问题描述】:

我有一个依赖于 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>

【问题讨论】:

    标签: java maven xerces


    【解决方案1】:

    默认情况下,当在依赖树中找到相同的依赖时,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 
    

    对比

     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 及其依赖可能是一场噩梦对齐版本)。

    【讨论】:

    • 确实,我现在注意到的文档中似乎明确提到了这一点:maven.apache.org/guides/introduction/…
    • xml-apis 总是一个痛点。实际需要它的最后一个 Java 版本是 1.4(从 Java 5 开始,相关类默认位于 JRE 类库中),但是在许多相互冲突的版本中,有很多不同的东西依赖于它。我希望有一种方法可以指定全局排除 - “忽略对 xml-apis 的所有依赖项,无论它们来自何处”。
    • xml-apis 并不是这里唯一的痛点...... xercesImpl 是臭名昭著的。如果可以,请逃跑。
    • 有趣我一直以为maven会选择更高版本来解决依赖关系。
    • @VinayLodha 然后在同一个 pom 的范围内使用最近的胜利。简而言之,在这种情况下,AFAIK 取决于它们在 pom 中定义的顺序。
    【解决方案2】:

    它是必需的,因为 Maven 不知道它应该选择哪个版本,所以 Maven 使用最近赢策略来选择使用哪个版本。最近获胜策略是documented in Maven documentation

    在您提供的依赖项 tee 中,版本 1.0.b2 显然是最接近的,因此行为就像设计的那样工作。

    您可能想查看之前讨论过的this thread(我无法确定该线程是否与此重复)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-29
      • 2012-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-16
      相关资源
      最近更新 更多