问题
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!
回答1:
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
.
回答2:
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
回答3:
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.
回答4:
This error can be resolved by disabling the generic Fault handling feature on IBM Websphere Application Servers.
In order to disable this property navigate to the Admin Console > Servers > Application Servers > > Process Definition > Java Virtual Machine > Custom Properties.
Enter the Key as 'webservice.unify.faults' and value as 'false'.
Once updated restart your server and install the EARs to get the Custom WSDL errors for your SOAP transactions.
回答5:
I had the same issue after upgrading the WAS FP 8.5.5.10 to 8.5.5.12. We had two Services with exactly same method name but different targetNameSpace,like DomainService1 has 'get' method and DomainService2 also has 'get' method, but WAS 8.5.5.12 throws this exception and doesn't give any clue to find the root cause. Apparently WAS is more strict in recent version with the naming of the methods.
This was the exception: org.apache.axis2.jaxws.wrapper.impl.JAXBWrapperException: An internal assertion error occurred. The com.xxx.web.myapp.services.jaxws.GetResponse JAXB object does not have a xxxxxStatus xml
After changing the name of the method specific to each service 'getABC' and 'getPQR' it worked!!!
hope this works!
来源:https://stackoverflow.com/questions/12805119/jax-ws-server-side-soaphandler-that-returns-fault-gets-internal-error-on-websp