ClassCastException:org.apache.xerces.parsers.XIncludeAwareParserConfiguration无法强制转换为org.apache.xerces.xni.parser.XMLParserConfiguration

我正在Eclipse中开发一个GWT应用程序并使用jdom2来读取一些自定义的xml属性文件。

在最近的更新之后,我的应用程序现在在尝试读取xml文件时失败并出现上述错误。 相关的堆栈跟踪是:

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) 

研究此问题表明,当类路径上存在不兼容的xerces jar版本时,可能会出现错误。

gwt-dev-2.6.1.jar包含xerces包,我的预感是这个最新版本的gwt-dev捆绑了一个不兼容的版本。 然而,当前版本的jdom2.0.5与2.11版本的Xerces一起发布,这似乎是Apache最新发布的版本。 将这些jar放在我的类路径上似乎并不能解决问题; 我以前能够依赖gwt-dev中的版本。

我宁愿在这方面做到这一点,而且远远超出了我的舒适区。

当我将项目从GWT 2.7升级到GWT 2.8时,我遇到了同样的exception。 我不知道为什么我没有GWT 2.7的这个问题(也许Eclipse项目的.classpath文件中的不同位置会影响它)。

这个例外的原因是之前有这样的代码:

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

使用了JDK包com.sun.org.apache.xerces.internal.jaxp的实现,但在升级到GWT2.8后,我的应用程序选择了gwt-dev.jar中的xerces。 我根据Javadoc找到了解决方法,并将此处链接到已使用的系统属性

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

在我的情况下,我通过添加到引导实体(运行配置中的类路径选项卡)两个条目/xml-apis/xml-apis/1.4.01/xml-apis-1.4.01.jar和/xerces/xercesImpl/2.11解决了这个问题。来自我当地的maven存储库的.0 / xercesImpl-2.11.0.jar

类路径上的jar的顺序很重要。 您是否尝试在类路径的开头添加Xerces 2.11 jar,以便首先加载它?

不要与Maven战斗:如果不一起使用,它们应该分开使用maven模块。 在您的情况下,JDom(可能)在服务器端使用,它不需要gwt-dev。 因此,解决方案是将项目拆分为多个Maven模块:一个用于依赖于GWT的客户端,另一个用于服务器端,而不是(如果使用GWT-RPC,则可能在gwt-servlet上,或者在requestfactory-server上,如果你使用RequestFactory)。

也就是说,即使只有一个项目,如果你在运行时在类路径中有gwt-dev,那么你的POM就会出错。

…除非你在构建时读取XML文件?

在我的情况下,通过删除本地sbt缓存中的xerces目录(如果使用maven,本地maven存储库)以及重建项目来解决此问题。

这有点晚了,但在阅读完答案之后我确实找到了解决这个问题的方法。 而不是使用普通的DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();构建文档工厂DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 你可以使用newInstance的参数来专门选择。 这样您就不必像上面的Svarog回答那样添加JVM参数,也不必添加或删除库。 我的解决方案如下:

 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"));