使用命名空间评估 xpath 表达式时出现 IncompleteClassChangeError
我需要修改一个具有多个命名空间的 xml 文档。我的代码在本地计算机上运行没有问题,但当我将其部署到 IBM Websphere 应用程序服务器时遇到 java.lang.IncompleteClassChangeError 。
我正在使用 xercesImpl-2.8.1.jar 和 xalan-2.7.0.jar。 是什么导致了这个错误以及如何解决它?或者,是否有其他方法可以通过命名空间支持来修改 xml 文档?
代码:
System.setProperty("javax.xml.parsers.DocumentBuilderFactory", "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
org.w3c.dom.Document doc = db.parse(new java.io.FileInputStream("c:/test.xml"));
System.setProperty("javax.xml.xpath.XPathFactory", "org.apache.xpath.jaxp.XPathFactoryImpl");
XPathFactory xf = XPathFactory.newInstance();
XPath xpath = xf.newXPath();
xpath.setNamespaceContext(new MyNamespaceContext());
// get the node for editing
String xpathExpr = ...
org.w3c.dom.Node n = (org.w3c.dom.Node)xpath.compile(xpathExpr).evaluate(doc, XPathConstants.NODE); // IncompatibleClassChangeError here
异常堆栈跟踪:
java.lang.IncompatibleClassChangeError
at org.apache.xpath.jaxp.JAXPPrefixResolver.getNamespaceForPrefix(JAXPPrefixResolver.java:45)
at org.apache.xpath.compiler.Lexer.mapNSTokens(Lexer.java:587)
at org.apache.xpath.compiler.Lexer.tokenize(Lexer.java:265)
at org.apache.xpath.compiler.Lexer.tokenize(Lexer.java:96)
at org.apache.xpath.compiler.XPathParser.initXPath(XPathParser.java:110)
at org.apache.xpath.XPath.<init>(XPath.java:176)
at org.apache.xpath.XPath.<init>(XPath.java:264)
at org.apache.xpath.jaxp.XPathImpl.compile(XPathImpl.java:394)
at com.ibm._jsp._xml._jspService(_xml.java:94)
at com.ibm.ws.jsp.runtime.HttpJspBase.service(HttpJspBase.java:87)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1146)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:592)
at com.ibm.ws.wswebcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:525)
at com.ibm.wsspi.webcontainer.servlet.GenericServletWrapper.handleRequest(GenericServletWrapper.java:122)
at com.ibm.ws.jsp.webcontainerext.AbstractJSPExtensionServletWrapper.handleRequest(AbstractJSPExtensionServletWrapper.java:232)
at com.ibm.ws.webcontainer.webapp.WebApp.handleRequest(WebApp.java:3548)
at com.ibm.ws.webcontainer.webapp.WebGroup.handleRequest(WebGroup.java:269)
at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:831)
at com.ibm.ws.wswebcontainer.WebContainer.handleRequest(WebContainer.java:1478)
at com.ibm.ws.webcontainer.channel.WCChannelLink.ready(WCChannelLink.java:133)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:458)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleNewInformation(HttpInboundLink.java:387)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.ready(HttpInboundLink.java:267)
at com.ibm.ws.ssl.channel.impl.SSLConnectionLink.determineNextChannel(SSLConnectionLink.java:1037)
at com.ibm.ws.ssl.channel.impl.SSLConnectionLink$MyReadCompletedCallback.complete(SSLConnectionLink.java:644)
at com.ibm.ws.ssl.channel.impl.SSLReadServiceContext$SSLReadCompletedCallback.complete(SSLReadServiceContext.java:1818)
at com.ibm.ws.tcp.channel.impl.AioReadCompletionListener.futureCompleted(AioReadCompletionListener.java:165)
at com.ibm.io.async.AbstractAsyncFuture.invokeCallback(AbstractAsyncFuture.java:217)
at com.ibm.io.async.AsyncChannelFuture.fireCompletionActions(AsyncChannelFuture.java:161)
at com.ibm.io.async.AsyncFuture.completed(AsyncFuture.java:136)
at com.ibm.io.async.ResultHandler.complete(ResultHandler.java:196)
at com.ibm.io.async.ResultHandler.runEventProcessingLoop(ResultHandler.java:751)
at com.ibm.io.async.ResultHandler$2.run(ResultHandler.java:881)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1497)
i need to modify an xml document which has multiple namespaces. my code runs without problems on my local machine but i'm encountering java.lang.IncompatibleClassChangeError when i deployed it to IBM Websphere application server.
i'm using xercesImpl-2.8.1.jar and xalan-2.7.0.jar.
what is causing this error and how do i resolve it? alternatively, are there other ways to modify xml documents with namespace support?
Code:
System.setProperty("javax.xml.parsers.DocumentBuilderFactory", "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
org.w3c.dom.Document doc = db.parse(new java.io.FileInputStream("c:/test.xml"));
System.setProperty("javax.xml.xpath.XPathFactory", "org.apache.xpath.jaxp.XPathFactoryImpl");
XPathFactory xf = XPathFactory.newInstance();
XPath xpath = xf.newXPath();
xpath.setNamespaceContext(new MyNamespaceContext());
// get the node for editing
String xpathExpr = ...
org.w3c.dom.Node n = (org.w3c.dom.Node)xpath.compile(xpathExpr).evaluate(doc, XPathConstants.NODE); // IncompatibleClassChangeError here
exception stack trace:
java.lang.IncompatibleClassChangeError
at org.apache.xpath.jaxp.JAXPPrefixResolver.getNamespaceForPrefix(JAXPPrefixResolver.java:45)
at org.apache.xpath.compiler.Lexer.mapNSTokens(Lexer.java:587)
at org.apache.xpath.compiler.Lexer.tokenize(Lexer.java:265)
at org.apache.xpath.compiler.Lexer.tokenize(Lexer.java:96)
at org.apache.xpath.compiler.XPathParser.initXPath(XPathParser.java:110)
at org.apache.xpath.XPath.<init>(XPath.java:176)
at org.apache.xpath.XPath.<init>(XPath.java:264)
at org.apache.xpath.jaxp.XPathImpl.compile(XPathImpl.java:394)
at com.ibm._jsp._xml._jspService(_xml.java:94)
at com.ibm.ws.jsp.runtime.HttpJspBase.service(HttpJspBase.java:87)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1146)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:592)
at com.ibm.ws.wswebcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:525)
at com.ibm.wsspi.webcontainer.servlet.GenericServletWrapper.handleRequest(GenericServletWrapper.java:122)
at com.ibm.ws.jsp.webcontainerext.AbstractJSPExtensionServletWrapper.handleRequest(AbstractJSPExtensionServletWrapper.java:232)
at com.ibm.ws.webcontainer.webapp.WebApp.handleRequest(WebApp.java:3548)
at com.ibm.ws.webcontainer.webapp.WebGroup.handleRequest(WebGroup.java:269)
at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:831)
at com.ibm.ws.wswebcontainer.WebContainer.handleRequest(WebContainer.java:1478)
at com.ibm.ws.webcontainer.channel.WCChannelLink.ready(WCChannelLink.java:133)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:458)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleNewInformation(HttpInboundLink.java:387)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.ready(HttpInboundLink.java:267)
at com.ibm.ws.ssl.channel.impl.SSLConnectionLink.determineNextChannel(SSLConnectionLink.java:1037)
at com.ibm.ws.ssl.channel.impl.SSLConnectionLink$MyReadCompletedCallback.complete(SSLConnectionLink.java:644)
at com.ibm.ws.ssl.channel.impl.SSLReadServiceContext$SSLReadCompletedCallback.complete(SSLReadServiceContext.java:1818)
at com.ibm.ws.tcp.channel.impl.AioReadCompletionListener.futureCompleted(AioReadCompletionListener.java:165)
at com.ibm.io.async.AbstractAsyncFuture.invokeCallback(AbstractAsyncFuture.java:217)
at com.ibm.io.async.AsyncChannelFuture.fireCompletionActions(AsyncChannelFuture.java:161)
at com.ibm.io.async.AsyncFuture.completed(AsyncFuture.java:136)
at com.ibm.io.async.ResultHandler.complete(ResultHandler.java:196)
at com.ibm.io.async.ResultHandler.runEventProcessingLoop(ResultHandler.java:751)
at com.ibm.io.async.ResultHandler$2.run(ResultHandler.java:881)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1497)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我通常的经验法则是,IncompleteClassChangeError 意味着编译器在编译时看到的某些类的版本与运行时加载的同一类的版本不兼容。堆栈跟踪显示 XPath 引擎正在对您的 NamespaceResolver 进行回调,因此应该重点关注调查。
My usual rule-of-thumb is that IncompatibleClassChangeError means that the version of some class that was seen by the compiler at compile time is incompatible with the version of the same class that is loaded at run-time. The stack trace shows that the XPath engine is doing a callback to your NamespaceResolver, so that should focus the investigation.
我的猜测是,websphere 在共享类路径中有另一个版本的 xerces 或 xalan 的副本,并且您的应用程序最终会使用不同版本的混合。我首先会尝试找出 websphere 使用哪个版本以及您的应用程序是否可以使用该版本。
如果您使用的是 Java 6,您还可以尝试使用 newInstance 方法采用类名和类加载器并传递您的 webapps 上下文类加载器。
My guess would be that websphere has a copy of another version of xerces or xalan in a shared classpath and your application ends up using a mix of different versions. I would first try to find out which version is used by websphere and whether your application works with that.
If you are on Java 6 you could also try to use the newInstance methods taking a classname and classloader and pass your webapps context classloader.
我已经设法解决了这个问题。这是由于从我也在使用的 xml-apis.jar 加载了一个类文件(
javax.xml.namespace.NamespaceContext
)。javax.xml.namespace.NamespaceContext
是 xml-apis.jar 和 JRE 中存在的接口。在该类的 JRE 版本中,接口方法都标记为“抽象”,但在 xml-apis.jar 版本中,接口方法不是抽象的。我相信这导致了二进制兼容性问题,导致我遇到了错误。所以解决我的问题,我更改了类加载器配置,在应用程序类加载器之前使用父类加载器,以便使用 JRE 中的 javax.xml.namespace.NamespaceContext 。
i've managed to solve this. it was due to a class file (
javax.xml.namespace.NamespaceContext
) being loaded from the xml-apis.jar which i was also using.javax.xml.namespace.NamespaceContext
is an interface present in xml-apis.jar and JRE. in the JRE's version of the class, the interface methods are all marked 'abstract' but in the xml-apis.jar's version, the interface methods are not abstract. i believe this caused a binary compatibility issue resulting in the error that i encountered.so resolve my problem, i changed my classloader configuration to use the parent classloader before the application classloader so that the
javax.xml.namespace.NamespaceContext
from the JRE is used.