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!
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
.
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With