Feb 24th, 2008, 09:19 PM
Large Message causing CPU Thrash
I have a project that exposes many calls through Spring WS, and I have a client that calls the web services.
On the server side I am marshalling an object with castor and populating the payload of my soap message with the resulting xml. I have noticed that when the XML gets large in the case when I'm marshalling more complex objects, the following call from the client locks up for minutes:
soapresponse = connection.call(callMessage, clsUrl);
The same call runs fine 99% of the time, and I have taken a look at what is contained in one of the payloads that is having the problem. Its size is about 220k. The CPU stays at around 85% while the call is processing.
I have tried switching to the AxiomSoapMessageFactory, but it didn't help.
Does anyone have any suggestions on how to debug this? I am considering grabbing the source of Spring WS so that I can step into the code and see where the problem is, but I wanted to see if anyone had any ideas first.
Feb 28th, 2008, 06:06 AM
There are two issues here.
The issue on the server-side is that Axiom only provides streaming access for incoming messages, not outgoing messages. This is due to the nature of the interceptor pipeline and the layout a SOAP Envelope: interceptors are executed after the response payload has been created, to add additional SOAP Headers, etc. In the layout of an envelope, the headers are written first, so that's why Axiom caches outgoing messages in memory before writing them.
I've been thinking about writing a really simple StreamingSoapMessageFactory, which does not support SOAP headers, but does outwards streaming, by getting a reference to the OutputStream of the currently used transport. This should be possible, but I simply don't have the time to implement it yet.
On the client-side, it looks like you're using plain SAAJ. The connection.call() method blocks until it reads the entire message in memory. You might want to consider using the Spring-WS's WebServiceTemplate in combination with Axiom (and payloadCaching false), since then you are directly streaming the incoming XML into a Result, or unmarshaller.