[SWS-496] SpringWS client does not send Mtom attachments - it inlines them instead. Created: 24/Mar/09  Updated: 04/May/12  Resolved: 17/May/09

Status: Closed
Project: Spring Web Services
Component/s: None
Affects Version/s: 1.5.6
Fix Version/s: 1.5.7

Type: Bug Priority: Major
Reporter: Sander Hartogensis Assignee: Arjen Poutsma
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Vista, JDK6, Tomcat 5.5.27, Axiom 1.2.8.

Attachments: Zip Archive mtomtest.zip     Text File spring-ws_mtom_client.patch    
Reference URL: http://forum.springframework.org/showthread.php?t=67669


The actual problem that I have is that I cannot send large attachments with SpringWS-client.

I suspect the cause is that MTOM encoding in Spring does not work, even though mtomEnabled in org.springframework.oxm.jaxb.Jaxb2Marshaller is set to true. Without MTOM encoding the whole attachment is inlined, in memory, and then OutOfMemoryErrors can quickly occur.

With a Tcp monitor you can see that MTOM does in not work, while it does work with Axis. I demonstrate this in an Eclipse project, that I will try to attach to this issue.

Because of this, we are now forced to use Axis in our otherwise Spring-dominated project. This is quite unsatisfying.

Comment by Sander Hartogensis [ 24/Mar/09 ]

mtomtest is an Eclipse project, created with the purpose of demonstrating problems with mtom on SpringWS-client. It contains a SpringWS server, and tests for both a SpringWS cient and an Axis client.
The project contains a pom which can build a war file. You have to deploy that yourself, because the project is not an Eclipse Dynamic Web Project. You do need the Maven-Eclipse plugin.
I have removed the output directory, so first build it with Eclipse so you can run the tests.

File locations
application context and SpringWS configuration is in src/main/webapp/WEB-INF/mtomtest-servlet-config.xml

Tests are in:

Warning about tcp monitoring
If you want to monitor sending big requests, you should use apache's TCPMon, as Eclipse's monitor slows the big upload down too much.

Tested with JDK6, Eclipse 3.4.1 (M20080911-1700), Tomcat 5.5.27

Comment by Joris Kuipers [ 03/Apr/09 ]

This is a test: I just spend half an hour typing a comment on my findings for this issue and lost them all when I pressed 'Add', as JIRA gave me an error that the issue didn't exist anymore...
I'll try again if this comes through OK.

Comment by Joris Kuipers [ 03/Apr/09 ]

I did some investigation and found the following issues:
1) Spring-WS's Jaxb2Marshaller$Jaxb2AttachmentMarshaller.isXOPPackage() should probably call mimeContainer.isXopPackage(), but is implemented to call mimeContainer.convertToXopPackage() instead. This always returns false, so JAXB2's XMLSerializer.startDocument won't use an instance of MTOMXmlOutput to wrap the SAXOutput.
2) When this is fixed, AxiomSoapMessage.isXopPackage still returns false b/o an expected bug in Axis2. This should be true for proper MTOM encoding
3) When this is hacked to always return true, a message is sent to the server. However, AxiomSoapMessage.getAttachment won't find the attachment for the given contentId, which is something like "[email protected]". It looks like this is not written out to the request properly.
4) When switching to SAAJ on the client but leaving the classpath intact, you get an error like this:
org.w3c.dom.DOMException: HIERARCHY_REQUEST_ERR: An attempt was made to insert a node where it is not permitted.
at org.apache.axiom.om.impl.dom.NodeImpl.insertBefore(NodeImpl.java:261)
at org.apache.axiom.om.impl.dom.NodeImpl.appendChild(NodeImpl.java:240)
at com.sun.xml.bind.marshaller.SAX2DOMEx.startElement(SAX2DOMEx.java:176)
at com.sun.xml.bind.v2.runtime.output.SAXOutput.endStartTag(SAXOutput.java:124)
at com.sun.xml.bind.v2.runtime.output.MTOMXmlOutput.endStartTag(MTOMXmlOutput.java:101)
at com.sun.xml.bind.v2.runtime.XMLSerializer.endAttributes(XMLSerializer.java:302)
at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsSoleContent(XMLSerializer.java:588)
at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeRoot(ClassBeanInfoImpl.java:312)
at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:490)
at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:328)
at com.sun.xml.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:257)
at org.springframework.oxm.jaxb.Jaxb2Marshaller.marshal(Jaxb2Marshaller.java:379)
at org.springframework.ws.support.MarshallingUtils.marshal(MarshallingUtils.java:81)
at org.springframework.ws.client.core.WebServiceTemplate$2.doWithMessage(WebServiceTemplate.java:360)
at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:535)
at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:502)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:351)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:341)
at mtomtest.test.TestWithSpringWsClient.sendFileAtPath(TestWithSpringWsClient.java:41)

5) When removing the Axis-SAAJ jars from the classpath, a request is sent but its Content-Type headers doesn't contain application/xop+xml, just text/xml

This doesn't solve the issue yet, but it should certainly help the next person who works on the issue.

Comment by Tareq Abedrabbo [ 17/Apr/09 ]

I created a spring-ws client for the included mtom sample. To run the client: ant run.
It works correctly with Saaj but not with Axiom.

Comment by Arjen Poutsma [ 17/May/09 ]

I've added Tareq's SAAJ client, and also an Atom client that uses the native API. See AxiomMtomClient. It's not pretty, but it works, and is faster than SAAJ too!

Comment by Arjen Poutsma [ 04/May/12 ]

Closing old issues

Generated at Fri Dec 15 06:36:27 UTC 2017 using JIRA 6.4.14#64029-sha1:ae256fe0fbb912241490ff1cecfb323ea0905ca5.