JAX-WS server-side SOAPHandler that returns fault gets "Internal Error" on WebSphere v8

user1717528 picture user1717528 · Oct 9, 2012 · Viewed 32.4k times · Source

I have a server-side JAX-WS SOAPHandler (on WebSphere v8) that in certain cases needs to respond to the client with a SOAP response that it has in a String variable (let's call it responseXml).

When responseXml contains a successful (i.e., non-fault) SOAP message, JAX-WS sends the response to the client correctly. However, when responseXml contains a SOAP fault message, an "Internal Error" occurs, and the client gets a different fault response than the one in responseXml, as shown here:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Body>
      <soapenv:Fault xmlns:axis2ns1="http://schemas.xmlsoap.org/soap/envelope/">
         <faultcode>axis2ns1:Server</faultcode>
         <faultstring>Internal Error</faultstring>
         <detail/>
      </soapenv:Fault>
   </soapenv:Body>
</soapenv:Envelope>

The following error is written to the console:

[10/9/12 12:21:04:177 EDT] 00000025 AxisEngine    E org.apache.axis2.engine.AxisEngine receive An error was detected during JAXWS processing
                             org.apache.axis2.AxisFault: An error was detected during JAXWS processing
at org.apache.axis2.jaxws.server.JAXWSMessageReceiver.receive(JAXWSMessageReceiver.java:208)
at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:198)
at org.apache.axis2.transport.http.HTTPTransportUtils.processHTTPPostRequest(HTTPTransportUtils.java:172)
at com.ibm.ws.websvcs.transport.http.WASAxis2Servlet.doPost(WASAxis2Servlet.java:1466)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:595)
...

Here is a simplified SOAPHandler that illustrates this problem. (Note that the value of responseXml shown here is just an example. In my actual SOAPHandler, the responses are not hard-coded but are read from a database. I'm just trying to show the simplest sample code possible.)

package simplified.demo;

import java.io.ByteArrayInputStream;
import java.util.Set;

import javax.xml.namespace.QName;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;

public class FaultyHandler implements SOAPHandler<SOAPMessageContext> {

    @Override
    public boolean handleMessage(SOAPMessageContext context) {
        Boolean outbound = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

        if (!outbound) {
            String responseXml = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"><soapenv:Header></soapenv:Header><soapenv:Body><soapenv:Fault><faultcode>soapenv:Server</faultcode><faultstring>ORA-01031: insufficient privileges</faultstring><detail/></soapenv:Fault></soapenv:Body></soapenv:Envelope>";
            try {
                SOAPMessage newMsg = createSOAPMessage(responseXml);
                context.setMessage(newMsg);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }

        return (outbound);
    }

    private SOAPMessage createSOAPMessage(String responseXml) {
        try {
            ByteArrayInputStream in = new ByteArrayInputStream(responseXml.getBytes());
            MessageFactory messageFactory = MessageFactory.newInstance();
            return messageFactory.createMessage(null, in);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public boolean handleFault(SOAPMessageContext context) {
        return true;
    }

    @Override
    public Set<QName> getHeaders() {
        return null;
    }

    @Override
    public void close(MessageContext context) {
    }
}

I get the exact same error when I code the SOAPHandler to create a SOAPFault object (using a SOAPFactory) and throw it in a SOAPFaultException.

Based on the stack trace, I looked at the source code for JAXWSMessageReceiver, and it looks like under the covers, Axis2 is looking for a causedByException, but of course in this case there isn't one.

Does anyone know why this is happening or how it can be fixed? Thanks!

Answer

schnatterer picture schnatterer · Aug 19, 2015

I had the same problem and was able to solve it by disabling the unified fault handling (it's not a bug, it's a feature!).

On the WAS Developer console

https://<yourhost>/<yourport>/ibm/console/login.do

do as described here (for WAS8):

Click Servers > Server Types. , and either WebSphere application servers > server_name or WebSphere proxy servers > server_name. Next, in the Server Infrastructure section, click Java and process management > Process definition , and select either Control, Servant, or Adjunct. Then click Java virtual machine > Custom properties.

There, add a new property webservices.unify.faults and set the value to false.

enter image description here