11

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

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

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

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

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

[我想,对于细心的读者来说,这并不奇怪]

有什么建议么?

4

4 回答 4

7

而不是使用:

// 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/服务工程:带示例的文章

希望它仍然可以帮助某人。

加布里埃尔

于 2011-08-26T18:21:59.770 回答
6

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

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

使用经认可的标准覆盖机制。将xalan.jar、serializer.jar、xercesImpl.jar和xml-apis.jar放在JRE的\lib\endorsed目录下,运行时软件的安装位置

于 2010-06-24T17:57:52.883 回答
2

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

于 2010-06-24T13:25:21.580 回答
2

请注意,可以通过设置java.endorsed.dirs系统属性来支持库而不修改 jre。

看看在 jdk1.6 中使用 Endorsed 目录的确切方法是什么

于 2013-10-09T07:21:33.223 回答