Description

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.

Activity

Introduction
------------
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.

Sander Hartogensis
added a comment - 24/Mar/09 1:41 AM Introduction
------------
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:
src\test\java\mtomtest\test\TestWithSpringWsClient.java
src\test\java\mtomtest\test\TestWithAxisClient.java
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.
Environment
-----------
Tested with JDK6, Eclipse 3.4.1 (M20080911-1700), Tomcat 5.5.27

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.

Joris Kuipers
added a comment - 03/Apr/09 1:04 AM 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.

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.

Joris Kuipers
added a comment - 03/Apr/09 1:21 AM 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.