How to override 'org.apache.cxf.stax.maxChildElements' property value inside a TomEE container?

Viewed 8289

I've got a JAX-WS web service endpoint configured purely via annotations running in TomEE 7 environment. Basically, the method being called has to return a List<String> of all node names contained in a graph data structure. The response of such a request can contain more thank 50k elements.

With CXF 2.6.x this worked fine. However, when I call the WS-method under CXF 3.x (bundled in TomEE 7.x), the following exception is thrown on the server side:

org.apache.cxf.interceptor.Fault: Unmarshalling Error: Maximum Number of Child Elements limit (50000) Exceeded 
    at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:906)
    at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:712)
    at org.apache.cxf.jaxb.io.DataReaderImpl.read(DataReaderImpl.java:179)
    at org.apache.cxf.wsdl.interceptors.DocLiteralInInterceptor.handleMessage(DocLiteralInInterceptor.java:109)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
    at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:801)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1680)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1559)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1356)
    at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
    at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:653)
    at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
    at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:514)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:423)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:324)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:277)
    at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
    at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:139)
    at com.sun.proxy.$Proxy51.getAllNodeNames(Unknown Source)
Caused by: javax.xml.bind.UnmarshalException
 - with linked exception:
[javax.xml.stream.XMLStreamException: Maximum Number of Child Elements limit (50000) Exceeded]
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.handleStreamException(UnmarshallerImpl.java:485)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:417)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:394)
    at org.apache.cxf.jaxb.JAXBEncoderDecoder.doUnmarshal(JAXBEncoderDecoder.java:855)
    at org.apache.cxf.jaxb.JAXBEncoderDecoder.access$100(JAXBEncoderDecoder.java:102)
    at org.apache.cxf.jaxb.JAXBEncoderDecoder$2.run(JAXBEncoderDecoder.java:894)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.apache.cxf.jaxb.JAXBEncoderDecoder.unmarshall(JAXBEncoderDecoder.java:892)
    ... 21 more
Caused by: javax.xml.stream.XMLStreamException: Maximum Number of Child Elements limit (50000) Exceeded
    at com.ctc.wstx.sr.InputElementStack.push(InputElementStack.java:340)
    at com.ctc.wstx.sr.BasicStreamReader.handleStartElem(BasicStreamReader.java:2951)
    at com.ctc.wstx.sr.BasicStreamReader.nextFromTree(BasicStreamReader.java:2839)
    at com.ctc.wstx.sr.BasicStreamReader.next(BasicStreamReader.java:1073)
    at com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.bridge(StAXStreamConnector.java:196)
    at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:415)
    ... 27 more
Error: Maximum Number of Child Elements limit (50000) Exceeded 

So far, I've read the official CXF documentation on this issue, checked a HowTo at the TomEE website and read many related, yet older posts in forums.

I tried to set the properties - as advised by the TomEE documentation - via openejb-jar.xml in the webservice's WEB-INF folder:

<?xml version="1.0" encoding="UTF-8"?>
<openejb-jar>
 <ejb-deployment ejb-name="MyWebService">
   <properties>
     org.apache.cxf.stax.maxChildElements = 100000
   </properties>
 </ejb-deployment>
</openejb-jar>

I also tried with the shorter property cxf.stax.maxChildElements to check whether this would be accepted, yet without success.

For testing/debugging, I start the TomEE instance via the tomee-maven-plugin, Therefore, I tried the set the maxChildElement property as an environment property like so:

<plugin>
    <groupId>org.apache.tomee.maven</groupId>
    <artifactId>tomee-maven-plugin</artifactId>
    <version>${tomee.plugin.version}</version>
    <configuration>
        <tomeeVersion>${tomee.version}</tomeeVersion>
        <tomeeClassifier>plus</tomeeClassifier>
        <debug>false</debug>
        <tomeeHttpPort>8181</tomeeHttpPort>
        <debugPort>5005</debugPort>
        <args>-Dfoo=bar</args>
        <skipCurrentProject>true</skipCurrentProject>
        <webapps>
            <webapp>my.ws:${webservice.artifact.name}:${webservice.artifact.version}?name=ws-endpoint</webapp>
        </webapps>
        <libs>
            <!-- Third party libraries needed in the global lib folder of TomEE -->
            <lib>log4j:log4j:${log4j.version}</lib>
        </libs>
        <systemVariables>
            <!--
                special property needed to allow for more childElements in StAX Parser
            -->
            <org.apache.cxf.stax.maxChildElement>100000</org.apache.cxf.stax.maxChildElement>
        </systemVariables>
    </configuration>
</plugin>

Sadly, it has no effect on the runtime configuration of CXF/StAX (Woodstox).

Question

How can we override the maxChildElements property via a configuration in openejb-jar.xml or as an external property at TomEE startup.

3 Answers

You can try -Dorg.apache.cxf.stax.maxChildElements=100000 It should also work

Related