【问题标题】:XercesImpl in conflict with JavaSE 6's internal xerces implementation. Both are needed... what can be done?XercesImpl 与 JavaSE 6 的内部 xerces 实现发生冲突。两者都需要......可以做什么?
【发布时间】:2011-03-07 19:38:44
【问题描述】:

我确信我不是第一个遇到这种冲突的人。

我继承的代码执行以下操作:

org.w3c.dom.Document dom; // declaration
javax.xml.validation.Schema schema; // declaration

...
...
...

javax.xml.validation.Validator validator = schema.newValidator();
validator.validate(new DOMSource(dom));

... 代表看似不重要/不相关的代码

使用 JDK 6 编译和运行代码是可行的(并且总是...)

最近我不得不将公司其他地方编写的另一个组件集成到我的代码中。该组件绝对需要包含在 xercesImpl-2.8.1.jar 的类路径中

我绝对需要这个第 3 方组件,但是现在运行上面的代码不再有效,我得到以下信息:

org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'Root'.
 at org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
 at org.apache.xerces.util.ErrorHandlerWrapper.error(Unknown Source)
 at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
 at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
 at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
 at org.apache.xerces.impl.xs.XMLSchemaValidator.handleStartElement(Unknown Source)
 at org.apache.xerces.impl.xs.XMLSchemaValidator.startElement(Unknown Source)
 at org.apache.xerces.jaxp.validation.DOMValidatorHelper.beginNode(Unknown Source)
 at org.apache.xerces.jaxp.validation.DOMValidatorHelper.validate(Unknown Source)
 at org.apache.xerces.jaxp.validation.DOMValidatorHelper.validate(Unknown Source)
 at org.apache.xerces.jaxp.validation.ValidatorImpl.validate(Unknown Source)
 at javax.xml.validation.Validator.validate(Validator.java:127)

作为一种解决方案,我曾想过以某种方式将 xercesImpl-2.8.1.jar 屏蔽在它自己的类加载器中,但没有设法这样做,可能是由于缺乏类加载器知识,或者可能是因为它不是要走的路。关于我的环境的另一件事,我的应用程序在 tomcat 5.5 和 6 上运行...

顺便说一句,在调试时我注意到,当我运行 dom.getImplementation()

  • 当添加 xercesImpl-2.8.1.jar 给 结果是类路径 org.apache.xerces.dom.DeferredDOMImplementationImpl@5f15c
  • 删除时结果为com.sun.org.apache.xerces.internal.dom.DeferredDOMImplementationImpl@6c6ae3

[我想你细心的读者不会感到惊讶]

有什么建议吗?

【问题讨论】:

    标签: java xml validation xerces jdk1.6


    【解决方案1】:

    请注意,通过设置java.endorsed.dirs 系统属性,可以在不修改 jre 的情况下支持库。

    what is the exact way to use Endorsed directory in jdk1.6

    【讨论】:

      【解决方案2】:

      而不是使用:

      // Uses first classloader-available implementation found:
      //import javax.xml.validation.SchemaFactory;
      SchemaFactory schemaFactory= SchemaFactory.newInstance(
          XMLConstants.W3C_XML_SCHEMA_NS_URI);
      

      尝试使用(自 Java 1.6 起):

      // Uses org.apache.xerces.jaxp.validation.XMLSchemaFactory subclass 
      //of SchemaFactory as implementation:
      //import javax.xml.validation.SchemaFactory;
      SchemaFactory schemaFactory= SchemaFactory.newInstance(
          XMLConstants.W3C_XML_SCHEMA_NS_URI,
          "org.apache.xerces.jaxp.validation.XMLSchemaFactory",
          null);
      

      查看相关的 JavaDoc。

      或使用 META-INF/服务工程:article with examples

      希望它仍然对某人有所帮助。

      加布里埃尔

      【讨论】:

        【解决方案3】:

        根据http://xml.apache.org/xalan-j/faq.html#faq-N100EF

        要使用较新版本的 Xalan-Java 并覆盖与 JDK 一起打包的版本:

        use the Endorsed Standards Override Mechanism。将xalan.jar、serializer.jar、xercesImpl.jar和xml-apis.jar放在JRE的\lib\endorsed目录下,这里是安装运行时软件的地方

        【讨论】:

        • 我已经完全按照您指定的方式完成了,但仍然存在冲突。我猜是因为在添加第 3 方组件之前存在的代码利用了 JDK 中的旧 API...
        • @Yaneeve - 我想你已经回答了你自己的问题。您将需要修改您的代码以使用其中一种,我会使用 JDK 附带的那种。也许如果您在每个可能有效的模块中完全限定您的课程?我会摆脱你添加的 Xercesimpl 并让它工作。
        【解决方案4】:

        首先要尝试的是把 xerces jar 放到 endorsed 目录中。这将导致整个 JVM 一致地使用 Xerces。这可能会解决整个问题,除非我不知道 2.8.1 有什么特别之处。

        【讨论】:

        • 你是指jdk背书的lib还是tomcat的?
        • 我在考虑JDK,但你可以先试试tomcat,看看是否有帮助。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-01-12
        • 1970-01-01
        • 1970-01-01
        • 2012-04-21
        • 1970-01-01
        • 2017-07-16
        相关资源
        最近更新 更多