My problem is similar to: JAX-WS SoapHandler with large messages: OutOfMemoryError and JAXWS Soap Handler Large MTOM Attachments
I am using tomcat, the Metro-Runtime-Configuration, and when I want to add a header in my HandlerChain
it gives me a OutOfMemory
exception.
public boolean handleMessage(SOAPMessageContext smc) {
if (Boolean.TRUE.equals(smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY))) {
SOAPMessage sm = smc.getMessage(); // <- OutOfMemory
...
In the first link Ahmed writes that I was able to write code that handles the raw data stream in 3 out of the 4 cases. Fortunately the three cases included the two we were mostly interested in: to/from the server.
but he doesn't provide a code snippet for that.
Things I tried:
The OutOfMemory
occurs in JDK7 AbstractMessageImpl#readAsSOAPMessage
which I wasn't able to override. Is it possible to override that class using a custom bootstrap? And how to do so? I was able to "override" the Integer
-class, but the AbstractMessageImpl
was not taken.
Changing the runtime to Apache CXF did not work with my generated JAX-WS RI Clients (Cannot create a secure XMLInputFactory
)
Is there another possibility to use another provider/runtime? And if not, how can I override JDK7's AbstractMessageImpl#readAsSOAPMessage
?
OR: is it possible to configure the order of MTOM and the handler chains? A MTOM'ed message shouldn't throw a OutOfMemory, is that right?
Thanks in advance crappi
This problem is also found in the ticket reports here: https://java.net/jira/browse/WSIT-1081
I solved this problem by not using a handler but adding a header when creating a port like this:
WebServiceEndpoint endpoint = w.getWebServiceEndpointPort(new MTOMFeature());
Map<String, Object> ctxt = ((BindingProvider) endpoint).getRequestContext();
// Enable HTTP chunking mode, otherwise HttpURLConnection buffers
ctxt.put("com.sun.xml.ws.transport.http.client.streaming.chunk.size", 8192);
WSBindingProvider bp = (WSBindingProvider) endpoint;
bp.setOutboundHeaders(Headers.create(JAXBContext.newInstance(WSSecurityHeader.class),
new WSSecurityHeader()));
Since Header-creation is not provided with methods, JAXB is used for complex header types.
@XmlRootElement(name = "Security")
public class WSSecurityHeader {
@XmlElement(name = "UsernameToken")
public WSSecurityUsernameToken usernameToken = new WSSecurityUsernameToken();
...
}
The client needs many libraries that this code is working: JAXB, JAX-WS, StreamBuffer, Policy, Stax-Ex, gmbal-api-only, which is horrible for just adding a header. (Especially if you are working with a fat client without maven support)