Question

My server is using XFire to handle web service request

But its CPU was taken up to 100% or sometimes even 1000%

When I restartd the server and after some request, this weird problem showed up again

I scan the thread dump,the thread that take up CPU is like this:

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)

It seems like XFire is parsing a XML file,but as time went by,the thread dump had no different at all,the thread was just like in a infinite loop.

However, I don't have enough experience with XFire,I can't figure out what cause the problem

I google a lot and find this topic whose phenomenon is just like mine

However,this topic suggest it may be a JVM bug and using JDK5 instead of JDK6.I am trying using JDK5 to see whether it would help

Is anyone encountered such problem? What cause this problem and how to fix it?

thx a lot.

Was it helpful?

Solution

Finally, I fixed this problem.

The reason causes this problem is the JDK6 XMLStreamReader implementation's bug, as this topic said.

How to fix it?

I read the XFire's source code ,the answer is in this code:

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

The STAXUtils.createXMLStreamReader will create XMLInputFactory to generate 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;
}

In this code, you can configure "xfire.stax.input.factory" XFire properties to generate XMLInputFactory whose XMLStreamReader has no bug, However, I can't figure out how to set this properties.

And in my project, xmlInputFactory is ths default xmlInputFactory which is JDK's.

 /**
* 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");
}

So, you can Use the javax.xml.stream.XMLInputFactory system property to use another XMLInputFactroy, such as wstx lib.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top