Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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!

like image 794
user1717528 Avatar asked Oct 09 '12 17:10

user1717528


3 Answers

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

like image 184
schnatterer Avatar answered Nov 10 '22 16:11

schnatterer


The actual problem is not the missing caused by exception, it is rather a unified fault handling in websphere:

http://www-01.ibm.com/support/docview.wss?uid=swg1PM58524

Either use the described workaround or install at least 8.0.0.4

like image 22
Thomas Avatar answered Nov 10 '22 14:11

Thomas


WebSphere starting with version 8 has a default enabled security feature, just returning the message "Internal Error". This is done to "preventing detailed information regarding why inbound message processing failed from being returned to message senders". Search for "webservices.unify.faults"

To disable this feature, add a -Dwebservices.unify.faults=false to your JVM custom properties.

like image 2
gregory Avatar answered Nov 10 '22 14:11

gregory