ClassCastException: org.apache.xerces.parsers.XIncludeAwareParserConfiguration no se puede convertir en org.apache.xerces.xni.parser.XMLParserConfiguration

Estoy desarrollando una aplicación GWT en Eclipse y uso jdom2 para leer algunos archivos de propiedades xml personalizados.

Después de una actualización reciente, mi aplicación ahora falla con el error anterior al intentar leer el archivo xml. El seguimiento de stack relevante es:

org.apache.xerces.parsers.XIncludeAwareParserConfiguration cannot be cast to org.apache.xerces.xni.parser.XMLParserConfiguration org.apache.xerces.parsers.SAXParser.(Unknown Source) org.apache.xerces.parsers.SAXParser.(Unknown Source) org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.(Unknown Source) org.apache.xerces.jaxp.SAXParserImpl.(Unknown Source) org.apache.xerces.jaxp.SAXParserFactoryImpl.newSAXParser(Unknown Source) org.jdom2.input.sax.XMLReaders.createXMLReader(XMLReaders.java:165) org.jdom2.input.SAXBuilder.createParser(SAXBuilder.java:871) org.jdom2.input.SAXBuilder.buildEngine(SAXBuilder.java:854) org.jdom2.input.SAXBuilder.getEngine(SAXBuilder.java:904) org.jdom2.input.SAXBuilder.build(SAXBuilder.java:1116) uk.co.platosys.db.jdbc.DatabaseProperties.loadProperties(DatabaseProperties.java:78) 

Investigar este problema sugiere que el error puede surgir cuando existen versiones incompatibles de los jars xerces en classpath.

gwt-dev-2.6.1.jar contiene los paquetes xerces y mi corazonada es que esta última versión de gwt-dev ha incluido una versión que no es compatible. Sin embargo, jdom2.0.5, la versión actual, se lanza con la versión 2.11 de Xerces, que parece ser la última lanzada por Apache. Poner estas jarras en mi classpath no parece resolver las cosas; Anteriormente he podido confiar en las versiones en gwt-dev.

Estoy bastante desconcertado acerca de esto y considerablemente fuera de mi zona de confort.

Tuve la misma excepción cuando actualicé mi proyecto de GWT 2.7 a GWT 2.8. No tengo idea de por qué no tuve este problema con GWT 2.7 (tal vez una posición diferente en el archivo .classpath del proyecto Eclipse podría afectarlo).

La razón de esa excepción fue que antes con un código como:

 DocumentBuilderFactory newInstance = DocumentBuilderFactory.newInstance(); DocumentBuilder newDocumentBuilder = newInstance.newDocumentBuilder(); baseLayoutXmlDocument = newDocumentBuilder.parse( baseLayoutSvgInputStream ); SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParser sp = spf.newSAXParser(); 

se usaron las implementaciones del paquete JDK com.sun.org.apache.xerces.internal.jaxp, pero después de actualizar a GWT2.8 mi aplicación eligió las xerces de gwt-dev.jar. Encontré la solución para eso de acuerdo con Javadoc y un enlace aquí a las propiedades de sistema usadas

 -Djavax.xml.parsers.DocumentBuilderFactory=com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl -Djavax.xml.parsers.SAXParserFactory=com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl 

En mi caso, resolví este problema agregando a las entidades bootstrap (pestaña Classpath en la configuración de ejecución) dos entradas /xml-apis/xml-apis/1.4.01/xml-apis-1.4.01.jar y /xerces/xercesImpl/2.11 .0 / xercesImpl-2.11.0.jar desde mi repository maven local

El orden de los flasks en el classpath importa. ¿Intentó agregar el jar Xerces 2.11 al comienzo del classpath para que se cargue primero?

No pelee con Maven: si las cosas no se usan juntas, deberían ir en módulos Maven separados. En su caso, JDom es (probablemente) utilizado en el lado del servidor, que no necesita gwt-dev. Entonces la solución es dividir su proyecto en varios módulos de Maven: uno para el lado del cliente que depende de GWT, y otro para el lado del servidor que no (o posiblemente en gwt-servlet si usa GWT-RPC, o en requestfactory-server si utiliza RequestFactory).

Dicho esto, incluso con un solo proyecto, si tienes gwt-dev en tu classpath en tiempo de ejecución, entonces tienes algo mal en tu POM.

… a menos que estés leyendo tus archivos XML en tiempo de comstackción?

En mi caso, esto se resolvió al eliminar el directorio xerces en mi sbt cache local (repository maven local si usa maven) y reconstruir el proyecto.

Esto es un poco tarde, pero después de leer las respuestas encontré una forma de evitar este problema. En lugar de construir su fábrica de documentos con el DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); normal DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); puede utilizar los parámetros en newInstance para elegir específicamente. De esta forma, no tiene que agregar parámetros de JVM como la respuesta de Svarog anterior, y no tiene que agregar o eliminar bibliotecas. Mi solución es la siguiente:

 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance("com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl", this.getClass().getClassLoader()); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(new FileInputStream("path/to/file.xml"));