2014-03-26 98 views
1

我的服務器來使用XFire處理Web服務請求在XFire中解析XML會導致CPU高?

但它的CPU被佔用100%,有時甚至1000%

當我restartd服務器,並有一定的要求後,這個奇怪的問題又出現了

我掃描的線程轉儲,即佔用CPU線程是這樣的:

httpWorkerThread-18028-39" daemon prio=10 tid=0xa0832800 nid=0x1d89 runnable [0x99e69000] 
java.lang.Thread.State: RUNNABLE 
at com.sun.xml.stream.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:892) 
at com.sun.xml.stream.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:362) 
at com.sun.xml.stream.XMLReaderImpl.next(XMLReaderImpl.java:568) 
at org.codehaus.xfire.soap.handler.ReadHeadersHandler.invoke(ReadHeadersHandler.java:44) 
at org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:131) 
at org.codehaus.xfire.transport.DefaultEndpoint.onReceive(DefaultEndpoint.java:64) 
at org.codehaus.xfire.transport.AbstractChannel.receive(AbstractChannel.java:38) 
at org.codehaus.xfire.transport.http.XFireServletController.invoke(XFireServletController.java:304) 
at org.codehaus.xfire.transport.http.XFireServletController.doService(XFireServletController.java:129) 
at org.codehaus.xfire.transport.http.XFireServlet.doPost(XFireServlet.java:116) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:753) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:846) 

好像XFire的是解析XML文件,但隨着時間的推移,該線程轉儲沒有不同的所有的線程就像無限循環一樣。

不過,我沒有用的XFire足夠的經驗,我想不出什麼緣故,我google了很多問題

,找到這個topic,其現象就像我

然而,這個話題表明它可能是一個JVM的錯誤,並使用JDK5而不是JDK6。我嘗試使用JDK5來查看它是否有幫助

有沒有人遇到過這樣的問題?是什麼導致了這個問題,以及如何解決它?

thx很多。

回答

0

最後,我解決了這個問題。

導致此問題的原因是JDK6 XMLStreamReader實現的bug,如此topic所述。

如何解決?

我讀的XFire的源代碼,得到的答案是這樣的代碼:

XMLStreamReader reader = 
      STAXUtils.createXMLStreamReader(request.getInputStream(), 
              charEncoding, 
              context); 

的STAXUtils.createXMLStreamReader將創建的XMLInputFactory生成XMLStreamReader的。

public static XMLInputFactory getXMLInputFactory(MessageContext ctx) 
{ 
    if (ctx == null) return xmlInputFactory; 

    Object inFactoryObj = ctx.getContextualProperty(XFire.STAX_INPUT_FACTORY); 

    if (inFactoryObj instanceof XMLInputFactory) 
    { 
     return (XMLInputFactory) inFactoryObj; 
    } 
    else if (inFactoryObj instanceof String) 
    { 
     String inFactory = (String) inFactoryObj; 
     XMLInputFactory xif = (XMLInputFactory) factories.get(inFactory); 
     if (xif == null) 
     { 
      xif = (XMLInputFactory) createFactory(inFactory, ctx); 
      configureFactory(xif,ctx); 
      factories.put(inFactory, xif); 
     } 
     return xif; 
    } 

    if(!inFactoryConfigured){ 
     configureFactory(xmlInputFactory,ctx); 
     inFactoryConfigured=true; 
    } 



    return xmlInputFactory; 
} 

在這段代碼中,你可以配置「xfire.stax.input.factory」 XFire的性質產生的XMLInputFactory其XMLStreamReader的沒有錯誤,但是,我想不出如何設置這個屬性。

而在我的項目中,xmlInputFactory是JDK的默認xmlInputFactory。

/** 
* Create a new instance of the factory. 
* This static method creates a new factory instance. 
* This method uses the following ordered lookup procedure to determine 
* the XMLInputFactory implementation class to load: 
* Use the javax.xml.stream.XMLInputFactory system property. 
* Use the properties file "lib/stax.properties" in the JRE directory. 
* This configuration file is in standard java.util.Properties format and contains 
* the fully qualified name of the implementation class with the key being the system property defined above. 
* Use the Services API (as detailed in the JAR specification), if available, to determine the classname. 
* The Services API will look for a classname in the file META-INF/services/javax.xml.stream.XMLInputFactory 
* in jars available to the runtime. 
* Platform default XMLInputFactory instance. 
* Once an application has obtained a reference to a XMLInputFactory 
* it can use the factory to configure and obtain stream instances. 
* 
* @throws FactoryConfigurationError if an instance of this factory cannot be loaded 
*/ 
public static XMLInputFactory newInstance() 
    throws FactoryConfigurationError 
{ 
    return (XMLInputFactory) FactoryFinder.find(
    "javax.xml.stream.XMLInputFactory", 
    "com.sun.xml.internal.stream.XMLInputFactoryImpl"); 
} 

所以,你可以使用javax.xml.stream.XMLInputFactory系統屬性使用另一個XMLInputFactroy,如wstx庫。