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)