2011-11-16 56 views
0

我需要修改具有多個名稱空間的xml文檔。我的代碼在本地機器上運行時沒有問題,但是當我將它部署到IBM Websphere應用程序服務器時遇到了java.lang.IncompatibleClassChangeError。評估具有名稱空間的xpath表達式時IncompatibleClassChangeError

我使用的是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) 

回答

0

我設法解決了這個問題。這是由於我正在使用的xml-apis.jar加載的類文件(javax.xml.namespace.NamespaceContext)。

javax.xml.namespace.NamespaceContext是一個存在於xml-apis.jar和JRE中的接口。在JRE的類的版本中,接口方法都標記爲「抽象」,但在xml-apis.jar的版本中,接口方法不是抽象的。我相信這會導致二進制兼容性問題,導致我遇到的錯誤。

所以解決了我的問題,我改變了我的類加載器配置,以便在應用程序類加載器之前使用父類加載器,以便使用來自JRE的javax.xml.namespace.NamespaceContext

2

我通常的原則進行的拇指是IncompatibleClassChangeError意味着一些類的版本,是由在編譯時,編譯器看到與在運行時加載的相同類的版本不兼容。堆棧跟蹤顯示XPath引擎正在對您的NamespaceResolver進行回調,因此應該重點調查。

0

我的猜測是websphere在共享類路徑中有另一個版本的xerces或xalan的副本,並且您的應用程序最終會使用不同版本的混合。我首先會試着找出websphere使用哪個版本,以及您的應用程序是否適用。

如果你使用Java 6,你也可以嘗試使用newInstance方法取類名和類加載器並傳遞你的web應用程序context classloader