Barnabas Bodnar created CXF-8125:
------------------------------------

             Summary: Support for using thread-safe application-defined 
StAX-factories
                 Key: CXF-8125
                 URL: https://issues.apache.org/jira/browse/CXF-8125
             Project: CXF
          Issue Type: Improvement
          Components: Core
    Affects Versions: 3.3.3
            Reporter: Barnabas Bodnar


CXF assumes, application-defined (contextual property of the message) 
StAX-factories are _not_ thread-safe and synchronizes accesses to them (eg. in 
_org.apache.cxf.interceptor.StaxInInterceptor_):
{noformat}
XMLInputFactory factory = getXMLInputFactory(message);
if (factory == null) {
 if (reader != null) {
 xreader = StaxUtils.createXMLStreamReader(reader);
 } else {
 xreader = StaxUtils.createXMLStreamReader(is, encoding);
 }
} else {
 synchronized (factory) {
 if (reader != null) {
 xreader = factory.createXMLStreamReader(reader);
 } else {
 xreader = factory.createXMLStreamReader(is, encoding);
 }
 }{noformat}
This is basically correct, because the StAX-spec doesn't require a 
_XMLInputFactory_ or a _XMLOutputFactory_ to be thread-safe.

However, this becomes problematic right with CXF's preferred 
StAX-implementation, WSTX, because it *performs I/O (reads a few bytes)* in 
_createXMLStreamReader()_:
{noformat}
    at java.io.FilterInputStream.read(FilterInputStream.java:133)
    at com.ctc.wstx.io.BaseReader.readBytes(BaseReader.java:155)
    at com.ctc.wstx.io.UTF8Reader.loadMore(UTF8Reader.java:369)
    at com.ctc.wstx.io.UTF8Reader.read(UTF8Reader.java:112)
    at 
com.ctc.wstx.io.ReaderBootstrapper.initialLoad(ReaderBootstrapper.java:254)
    at 
com.ctc.wstx.io.ReaderBootstrapper.bootstrapInput(ReaderBootstrapper.java:134)
    at com.ctc.wstx.stax.WstxInputFactory.doCreateSR(WstxInputFactory.java:573)
    at com.ctc.wstx.stax.WstxInputFactory.createSR(WstxInputFactory.java:633)
    at com.ctc.wstx.stax.WstxInputFactory.createSR(WstxInputFactory.java:657)
    at 
com.ctc.wstx.stax.WstxInputFactory.createXMLStreamReader(WstxInputFactory.java:342)
    at 
org.apache.cxf.interceptor.StaxInInterceptor.handleMessage(StaxInInterceptor.java:134)
    - locked <0x00000006f7ceef50> (a com.ctc.wstx.stax.WstxInputFactory)
{noformat}
If this synchronous read-operation blocks due to network issues, *all other 
incoming SOAP-requests are blocked*:
{noformat}
java.lang.Thread.State: BLOCKED (on object monitor)
    at 
org.apache.cxf.interceptor.StaxInInterceptor.handleMessage(StaxInInterceptor.java:130)
    - waiting to lock <0x00000006f7ceef50> (a 
com.ctc.wstx.stax.WstxInputFactory)
    at 
org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
    - locked <0x0000000781907170> (a org.apache.cxf.phase.PhaseInterceptorChain)
    at 
org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
    at 
org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:267)
    at 
org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234)
{noformat}
Even if performing I/O here is a questionable behavior of WSTX, unneeded 
synchronization should anyway be avoided for performance reasons. My proposal 
is to introduce a boolean contextual property indicating whether the provided 
factories are thread-safe and omit the synchronization, if set to _true_.



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to