XercesImpl конфликтует с реализацией внутренних xerces JavaSE 6. Оба нужны... что можно сделать?

Я уверен, что я не первый, кто столкнулся с этим конфликтом.

Код, который я унаследовал, делает следующее:

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

Я абсолютно требую этого стороннего компонента, но теперь работающий выше код больше не работает, и я получаю следующее:

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 к classpath результат [email protected]
  • при удалении его результат com.s[email protected]6c6ae3

[Неудивительно, что вы, чистые читатели, я полагаю]

Любые предложения?

Ответ 1

По http://xml.apache.org/xalan-j/faq.html#faq-N100EF

Чтобы использовать более новую версию Xalan-Java и переопределить пакет, упакованный с помощью JDK:

использовать механизм переопределения одобренных стандартов. Поместите xalan.jar, serializer.jar, xercesImpl.jar и xml-apis.jar в каталог\lib\одобренный JRE, где установлено программное обеспечение для выполнения.

Ответ 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/services: статья с примерами

Надеюсь, он все еще помогает кому-то.

Габриэль

Ответ 3

Первое, что нужно попробовать, - положить банку xerces в поддерживаемую директорию. Это приведет к тому, что весь JVM будет последовательно использовать Xerces. Это может решить всю проблему прямо там, если нет особого мнения о 2.8.1, о котором я не знаю.