处理“Xerces地狱"在 Java/Maven 中? [英] Dealing with "Xerces hell" in Java/Maven?

查看:16
本文介绍了处理“Xerces地狱"在 Java/Maven 中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的办公室,仅仅提到 Xerces 这个词就足以激起开发人员的杀气.粗略地看一下关于 SO 的其他 Xerces 问题似乎表明几乎所有 Maven 用户都被触及"过.在某个时候遇到这个问题.不幸的是,理解这个问题需要对 Xerces 的历史有所了解...

历史

  • Xerces 是 Java 生态系统中使用最广泛的 XML 解析器.几乎每个用 Java 编写的库或框架都在某种程度上使用 Xerces(如果不是直接的话,也可以传递).

  • 允许上传到 Maven 中心.投票/观看/贡献这个问题,让我们一劳永逸地解决这个问题.

    解决方案

    自 2013 年 2 月 20 日起,Maven Central 中有 2.11.0 JAR (和源 JAR!) 的 Xerces!请参阅 Maven 中心中的 Xerces.我想知道他们为什么没有解决 https://issues.apache.org/jira/browse/XERCESJ-1454...

    我用过:

    <依赖><groupId>xerces</groupId><artifactId>xercesImpl</artifactId><version>2.11.0</version></依赖>

    并且所有依赖项都已经很好地解决了 - 即使是正确的 xml-apis-1.4.01

    最重要的(过去并不明显) - Maven Central 中的 JAR 与官方 Xerces-J-bin.2.11.0.zip 中的 JAR 相同 分发.

    但是我找不到 xml-schema-1.1-beta 版本 - 由于额外的依赖,它不能是 Maven classifier-ed 版本.>

    In my office, the mere mention of the word Xerces is enough to incite murderous rage from developers. A cursory glance at the other Xerces questions on SO seem to indicate that almost all Maven users are "touched" by this problem at some point. Unfortunately, understanding the problem requires a bit of knowledge about the history of Xerces...

    History

    • Xerces is the most widely used XML parser in the Java ecosystem. Almost every library or framework written in Java uses Xerces in some capacity (transitively, if not directly).

    • The Xerces jars included in the official binaries are, to this day, not versioned. For example, the Xerces 2.11.0 implementation jar is named xercesImpl.jar and not xercesImpl-2.11.0.jar.

    • The Xerces team does not use Maven, which means they do not upload an official release to Maven Central.

    • Xerces used to be released as a single jar (xerces.jar), but was split into two jars, one containing the API (xml-apis.jar) and one containing the implementations of those APIs (xercesImpl.jar). Many older Maven POMs still declare a dependency on xerces.jar. At some point in the past, Xerces was also released as xmlParserAPIs.jar, which some older POMs also depend on.

    • The versions assigned to the xml-apis and xercesImpl jars by those who deploy their jars to Maven repositories are often different. For example, xml-apis might be given version 1.3.03 and xercesImpl might be given version 2.8.0, even though both are from Xerces 2.8.0. This is because people often tag the xml-apis jar with the version of the specifications that it implements. There is a very nice, but incomplete breakdown of this here.

    • To complicate matters, Xerces is the XML parser used in the reference implementation of the Java API for XML Processing (JAXP), included in the JRE. The implementation classes are repackaged under the com.sun.* namespace, which makes it dangerous to access them directly, as they may not be available in some JREs. However, not all of the Xerces functionality is exposed via the java.* and javax.* APIs; for example, there is no API that exposes Xerces serialization.

    • Adding to the confusing mess, almost all servlet containers (JBoss, Jetty, Glassfish, Tomcat, etc.), ship with Xerces in one or more of their /lib folders.

    Problems

    Conflict Resolution

    For some -- or perhaps all -- of the reasons above, many organizations publish and consume custom builds of Xerces in their POMs. This is not really a problem if you have a small application and are only using Maven Central, but it quickly becomes an issue for enterprise software where Artifactory or Nexus is proxying multiple repositories (JBoss, Hibernate, etc.):

    For example, organization A might publish xml-apis as:

    <groupId>org.apache.xerces</groupId>
    <artifactId>xml-apis</artifactId>
    <version>2.9.1</version>
    

    Meanwhile, organization B might publish the same jar as:

    <groupId>xml-apis</groupId>
    <artifactId>xml-apis</artifactId>
    <version>1.3.04</version>
    

    Although B's jar is a lower version than A's jar, Maven does not know that they are the same artifact because they have different groupIds. Thus, it cannot perform conflict resolution and both jars will be included as resolved dependencies:

    Classloader Hell

    As mentioned above, the JRE ships with Xerces in the JAXP RI. While it would be nice to mark all Xerces Maven dependencies as <exclusion>s or as <provided>, the third-party code you depend on may or may not work with the version provided in JAXP of the JDK you're using. In addition, you have the Xerces jars shipped in your servlet container to contend with. This leaves you with a number of choices: Do you delete the servlet version and hope that your container runs on the JAXP version? Is it better to leave the servlet version, and hope that your application frameworks run on the servlet version? If one or two of the unresolved conflicts outlined above manage to slip into your product (easy to happen in a large organization), you quickly find yourself in classloader hell, wondering which version of Xerces the classloader is picking at runtime and whether or not it will pick the same jar in Windows and Linux (probably not).

    Solutions?

    We've tried marking all Xerces Maven dependencies as <provided> or as an <exclusion>, but this is difficult to enforce (especially with a large team) given that the artifacts have so many aliases (xml-apis, xerces, xercesImpl, xmlParserAPIs, etc.). Additionally, our third party libs/frameworks may not run on the JAXP version or the version provided by a servlet container.

    How can we best address this problem with Maven? Do we have to exercise such fine-grained control over our dependencies, and then rely on tiered classloading? Is there some way to globally exclude all Xerces dependencies, and force all of our frameworks/libs to use the JAXP version?


    UPDATE: Joshua Spiewak has uploaded a patched version of the Xerces build scripts to XERCESJ-1454 that allows for upload to Maven Central. Vote/watch/contribute to this issue and let's fix this problem once and for all.

    解决方案

    There are 2.11.0 JARs (and source JARs!) of Xerces in Maven Central since 20th February 2013! See Xerces in Maven Central. I wonder why they haven't resolved https://issues.apache.org/jira/browse/XERCESJ-1454...

    I've used:

    <dependency>
        <groupId>xerces</groupId>
        <artifactId>xercesImpl</artifactId>
        <version>2.11.0</version>
    </dependency>
    

    and all dependencies have resolved fine - even proper xml-apis-1.4.01!

    And what's most important (and what wasn't obvious in the past) - the JAR in Maven Central is the same JAR as in the official Xerces-J-bin.2.11.0.zip distribution.

    I couldn't however find xml-schema-1.1-beta version - it can't be a Maven classifier-ed version because of additional dependencies.

    这篇关于处理“Xerces地狱"在 Java/Maven 中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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