You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-commits@axis.apache.org by ba...@apache.org on 2011/04/25 19:22:44 UTC
svn commit: r1096530 - in /axis/axis2/java/core/trunk/modules:
jaxws-integration/test/org/apache/axis2/jaxws/sample/
jaxws-integration/test/org/apache/axis2/jaxws/sample/addnumbershandler/
jaxws/src/org/apache/axis2/jaxws/ jaxws/src/org/apache/axis2/ja...
Author: barrettj
Date: Mon Apr 25 17:22:44 2011
New Revision: 1096530
URL: http://svn.apache.org/viewvc?rev=1096530&view=rev
Log:
On JAX-WS Client, treat local exceptions (e.g. ConnectException) as a SOAPFault, driving the JAX-WS handler handleFault methods and throwing a SOAPFAultException back through the client invocation. Also provide a property to revert to previous behavior of creating an empty message, driving the JAX-WS handler handleMessage methods, and throwing a WebServiceException back through the client invocation.
Modified:
axis/axis2/java/core/trunk/modules/jaxws-integration/test/org/apache/axis2/jaxws/sample/AddNumbersHandlerTests.java
axis/axis2/java/core/trunk/modules/jaxws-integration/test/org/apache/axis2/jaxws/sample/addnumbershandler/AddNumbersClientLogicalHandler3.java
axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/Constants.java
axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/client/dispatch/BaseDispatch.java
axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/client/proxy/JAXWSProxyHandler.java
axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/core/controller/impl/AxisInvocationController.java
axis/axis2/java/core/trunk/modules/metadata/src/org/apache/axis2/jaxws/ExceptionFactory.java
Modified: axis/axis2/java/core/trunk/modules/jaxws-integration/test/org/apache/axis2/jaxws/sample/AddNumbersHandlerTests.java
URL: http://svn.apache.org/viewvc/axis/axis2/java/core/trunk/modules/jaxws-integration/test/org/apache/axis2/jaxws/sample/AddNumbersHandlerTests.java?rev=1096530&r1=1096529&r2=1096530&view=diff
==============================================================================
--- axis/axis2/java/core/trunk/modules/jaxws-integration/test/org/apache/axis2/jaxws/sample/AddNumbersHandlerTests.java (original)
+++ axis/axis2/java/core/trunk/modules/jaxws-integration/test/org/apache/axis2/jaxws/sample/AddNumbersHandlerTests.java Mon Apr 25 17:22:44 2011
@@ -27,6 +27,7 @@ import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
+import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Future;
@@ -45,6 +46,7 @@ import javax.xml.ws.BindingProvider;
import javax.xml.ws.Dispatch;
import javax.xml.ws.Response;
import javax.xml.ws.Service;
+import javax.xml.ws.WebServiceException;
import javax.xml.ws.handler.Handler;
import javax.xml.ws.handler.HandlerResolver;
import javax.xml.ws.handler.PortInfo;
@@ -53,7 +55,11 @@ import javax.xml.ws.soap.SOAPFaultExcept
import junit.framework.Test;
import junit.framework.TestSuite;
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.description.Parameter;
+import org.apache.axis2.engine.AxisConfiguration;
import org.apache.axis2.jaxws.TestLogger;
+import org.apache.axis2.jaxws.description.ServiceDescription;
import org.apache.axis2.jaxws.framework.AbstractTestCase;
import org.apache.axis2.jaxws.sample.addnumbershandler.AddNumbersClientLogicalHandler;
import org.apache.axis2.jaxws.sample.addnumbershandler.AddNumbersClientLogicalHandler2;
@@ -64,11 +70,14 @@ import org.apache.axis2.jaxws.sample.add
import org.apache.axis2.jaxws.sample.addnumbershandler.AddNumbersHandlerPortType;
import org.apache.axis2.jaxws.sample.addnumbershandler.AddNumbersHandlerService;
import org.apache.axis2.jaxws.sample.addnumbershandler.AddNumbersProtocolHandler2;
+import org.apache.axis2.jaxws.spi.ServiceDelegate;
import org.test.addnumbershandler.AddNumbersHandlerResponse;
public class AddNumbersHandlerTests extends AbstractTestCase {
String axisEndpoint = "http://localhost:6060/axis2/services/AddNumbersHandlerService.AddNumbersHandlerPortTypeImplPort";
+ String invalidAxisEndpoint = "http://invalidHostName:6060/axis2/services/AddNumbersHandlerService.AddNumbersHandlerPortTypeImplPort";
+
static File requestFile = null;
static {
String resourceDir = System.getProperty("basedir",".")+
@@ -568,7 +577,6 @@ public class AddNumbersHandlerTests exte
fail("We should have got an exception due to the handler.");
} catch(Exception e) {
- e.printStackTrace();
assertTrue("Exception should be SOAPFaultException", e instanceof SOAPFaultException);
assertEquals(((SOAPFaultException)e).getMessage(), "I don't like the value 99");
@@ -828,7 +836,7 @@ public class AddNumbersHandlerTests exte
String log = readLogFile();
String expected_calls = "AddNumbersClientLogicalHandler4 HANDLE_MESSAGE_OUTBOUND\n"
- + "AddNumbersClientLogicalHandler3 HANDLE_FAULT_OUTBOUND\n"
+ + "AddNumbersClientLogicalHandler3 HANDLE_MESSAGE_OUTBOUND\n"
+ "AddNumbersClientLogicalHandler HANDLE_MESSAGE_OUTBOUND\n"
+ "AddNumbersClientLogicalHandler3 HANDLE_FAULT_INBOUND\n"
+ "AddNumbersClientLogicalHandler3 RETURNING FALSE INBOUND\n"
@@ -841,6 +849,103 @@ public class AddNumbersHandlerTests exte
TestLogger.logger.debug("----------------------------------");
}
+ /**
+ * Validate that a local exception (in this case a ConnectionException caused by an invalid
+ * host on the EPR) is returned as a SOAPFaultException, and the JAX-WS application handler
+ * handleFault() methods are driven. This is the default behavior.
+ */
+ public void testAddNumbersClientHandlerWithLocalException() {
+ try{
+ TestLogger.logger.debug("----------------------------------");
+ TestLogger.logger.debug("test: " + getName());
+
+ AddNumbersHandlerService service = new AddNumbersHandlerService();
+ AddNumbersHandlerPortType proxy = service.getAddNumbersHandlerPort();
+
+ BindingProvider p = (BindingProvider)proxy;
+
+ // Force a local connection exception by using an invalid host/port
+ p.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, invalidAxisEndpoint);
+
+ List<Handler> handlers = p.getBinding().getHandlerChain();
+ if (handlers == null)
+ handlers = new ArrayList<Handler>();
+ handlers.add(new AddNumbersClientLogicalHandler4());
+ handlers.add(new AddNumbersClientLogicalHandler2());
+
+ p.getBinding().setHandlerChain(handlers);
+
+ int total = proxy.addNumbersHandler(1,2);
+
+ fail("Should have got an exception, but we didn't.");
+ } catch(Exception e) {
+ assertTrue("Exception should be SOAPFaultException. Found " +e.getClass() + " "+ e.getMessage(), e instanceof SOAPFaultException);
+ SOAPFault soapFault = ((SOAPFaultException) e).getFault();
+ assertTrue("Cause should be instanceof UnknownHostException", (e.getCause() instanceof java.net.UnknownHostException));
+
+ String log = readLogFile();
+ String expected_calls = "AddNumbersClientLogicalHandler4 HANDLE_MESSAGE_OUTBOUND\n"
+ + "AddNumbersClientLogicalHandler2 HANDLE_MESSAGE_OUTBOUND\n"
+ + "AddNumbersClientLogicalHandler2 HANDLE_FAULT_INBOUND\n"
+ + "AddNumbersClientLogicalHandler4 HANDLE_FAULT_INBOUND\n"
+ + "AddNumbersClientLogicalHandler2 CLOSE\n"
+ + "AddNumbersClientLogicalHandler4 CLOSE\n";
+ assertEquals(expected_calls, log);
+
+ }
+ TestLogger.logger.debug("----------------------------------");
+ }
+
+ /**
+ * Validate that setting a property reverts the logic for how local exceptions are handled.
+ * Validate that a local exception (in this case a ConnectionException caused by an invalid
+ * host on the EPR) is returned as a WebServiceExcpetion (not a SOAPFaultException), and the
+ * JAX-WS application handler handleMessage() methods are driven.
+ */
+ public void testAddNumbersClientHandlerWithLocalException_RevertBehaviorFlag() {
+ try{
+ TestLogger.logger.debug("----------------------------------");
+ TestLogger.logger.debug("test: " + getName());
+
+ AddNumbersHandlerService service = new AddNumbersHandlerService();
+ setAxisConfigParameter(service, org.apache.axis2.jaxws.Constants.DISABLE_SOAPFAULT_FOR_LOCAL_EXCEPTION,
+ "true");
+ AddNumbersHandlerPortType proxy = service.getAddNumbersHandlerPort();
+
+ BindingProvider p = (BindingProvider)proxy;
+
+ // Force a local connection exception by using an invalid host/port
+ p.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, invalidAxisEndpoint);
+
+ List<Handler> handlers = p.getBinding().getHandlerChain();
+ if (handlers == null)
+ handlers = new ArrayList<Handler>();
+ handlers.add(new AddNumbersClientLogicalHandler4());
+ handlers.add(new AddNumbersClientLogicalHandler2());
+
+ p.getBinding().setHandlerChain(handlers);
+
+ int total = proxy.addNumbersHandler(1,2);
+
+ fail("Should have got an exception, but we didn't.");
+ } catch(Exception e) {
+ assertTrue("Exception should be WebServiceException.", e instanceof WebServiceException);
+ assertFalse("Exception should not be SOAPFaultException.", e instanceof SOAPFaultException);
+ assertTrue("Cause should be instanceof UnknownHostException", (e.getCause() instanceof java.net.UnknownHostException));
+
+ String log = readLogFile();
+ String expected_calls = "AddNumbersClientLogicalHandler4 HANDLE_MESSAGE_OUTBOUND\n"
+ + "AddNumbersClientLogicalHandler2 HANDLE_MESSAGE_OUTBOUND\n"
+ + "AddNumbersClientLogicalHandler2 HANDLE_MESSAGE_INBOUND\n"
+ + "AddNumbersClientLogicalHandler4 HANDLE_MESSAGE_INBOUND\n"
+ + "AddNumbersClientLogicalHandler2 CLOSE\n"
+ + "AddNumbersClientLogicalHandler4 CLOSE\n";
+ assertEquals(expected_calls, log);
+
+ }
+ TestLogger.logger.debug("----------------------------------");
+ }
+
public void testAddNumbersClientHandlerWithFalse() throws Exception {
AddNumbersClientLogicalHandler2 clh = new AddNumbersClientLogicalHandler2();
AddNumbersClientProtocolHandler cph = new AddNumbersClientProtocolHandler();
@@ -964,6 +1069,72 @@ public class AddNumbersHandlerTests exte
}
}
+ /**
+ * Validate the behavior of a local exception regarding JAX-WS application handlers for an async
+ * callback invocation.
+ *
+ * IMPORTANT NOTE: This is documenting the current behavior for an async callback invocation, which
+ * is different than a synchronous invocation. For async callback, if a local exception occurs, the
+ * JAX-WS handlers are not invoked again, unlike for a synchronous invocation. This behavior should
+ * probably be made consistent with the sync invocation flow through JAX-WS handlers.
+ * @see #testAddNumbersClientHandlerWithLocalException()
+ * @see #testAddNumbersClientHandlerWithLocalException_RevertBehaviorFlag()
+ *
+ */
+ public void testAddNumbersClientHandlerWithLocalExceptionAsync_RevertBehavior() {
+ try{
+ TestLogger.logger.debug("----------------------------------");
+ TestLogger.logger.debug("test: " + getName());
+
+ AddNumbersHandlerService service = new AddNumbersHandlerService();
+ AddNumbersHandlerPortType proxy = service.getAddNumbersHandlerPort();
+
+ BindingProvider p = (BindingProvider)proxy;
+
+ p.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, invalidAxisEndpoint);
+
+ List<Handler> handlers = p.getBinding().getHandlerChain();
+ if (handlers == null)
+ handlers = new ArrayList<Handler>();
+ handlers.add(new AddNumbersClientLogicalHandler4());
+ handlers.add(new AddNumbersClientLogicalHandler2());
+ p.getBinding().setHandlerChain(handlers);
+
+
+ AddNumbersHandlerAsyncCallback callback = new AddNumbersHandlerAsyncCallback();
+ Future<?> future = proxy.addNumbersHandlerAsync(10, 10, callback);
+
+ while (!future.isDone()) {
+ Thread.sleep(1000);
+ TestLogger.logger.debug("Async invocation incomplete");
+ }
+
+ int total = callback.getResponseValue();
+ assertEquals("Local exception should cause value to be 0", 0, total);
+ TestLogger.logger.debug("Total (after handler manipulation) = " + total);
+
+ Exception exception = callback.getException();
+ assertNotNull("Exception should be set", exception);
+
+ assertTrue("Exception should be ExecutionException.", exception instanceof java.util.concurrent.ExecutionException);
+ assertTrue("Cause should be Web Service Exception", exception.getCause() instanceof WebServiceException);
+
+ String log = readLogFile();
+ // IMPORTANT NOTE: Currently the JAX-WS handlers are not invoked after the local exception
+ // occurs trying to send the invocation. This is not necessarily correct and is different than
+ // the flow through the JAX-WS handlers for synchronous invocation. This test is validating CURRENT
+ // behavior, and not necessarily CORRECT behavior.
+ String expected_calls = "AddNumbersClientLogicalHandler4 HANDLE_MESSAGE_OUTBOUND\n"
+ + "AddNumbersClientLogicalHandler2 HANDLE_MESSAGE_OUTBOUND\n";
+ assertEquals(expected_calls, log);
+
+ TestLogger.logger.debug("----------------------------------");
+ } catch(Exception e) {
+ e.printStackTrace();
+ fail(e.toString());
+ }
+ }
+
public void testAddNumbersHandlerHandlerResolver() {
try {
System.out.println("----------------------------------");
@@ -1221,4 +1392,49 @@ public class AddNumbersHandlerTests exte
return null;
}
+ // These two methods enable a test spy, using the ServiceDelegate retrieved from a Service
+ // instance. The spy will allow an parameter to be set on the AxisConfig in order to unit test
+ // the property. This is NOT the way properties should be set on the config outside of a unit test
+ // environment. The correct way to set properties on the config is to specify them in the associated
+ // axis2.xml file.
+ static private void setAxisConfigParameter(Service service, String key, String value) {
+ ServiceDelegate delegate = getServiceDelegate(service);
+ ServiceDescription svcDesc = delegate.getServiceDescription();
+ AxisConfiguration axisConfig = svcDesc.getAxisConfigContext().getAxisConfiguration();
+ Parameter parameter = new Parameter(key, value);
+ try {
+ axisConfig.addParameter(parameter);
+ } catch (AxisFault e) {
+ fail("Unable to set Parameter on AxisConfig due to exception " + e);
+ }
+ }
+ static private ServiceDelegate getServiceDelegate(Service service) {
+ // Need to get to the private Service._delegate field in order to get to the ServiceDescription to test
+ ServiceDelegate returnServiceDelegate = null;
+ try {
+ try {
+// Field serviceDelgateField = service.getClass().getDeclaredFields()[0];
+ Field serviceDelgateField = service.getClass().getDeclaredField("delegate");
+ serviceDelgateField.setAccessible(true);
+ returnServiceDelegate = (ServiceDelegate) serviceDelgateField.get(service);
+ } catch (NoSuchFieldException e) {
+ // This may be a generated service subclass, so get the delegate from the superclass
+ Field serviceDelegateField = service.getClass().getSuperclass().getDeclaredField("delegate");
+ serviceDelegateField.setAccessible(true);
+ returnServiceDelegate = (ServiceDelegate) serviceDelegateField.get(service);
+ }
+ } catch (SecurityException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (IllegalAccessException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (NoSuchFieldException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return returnServiceDelegate;
+ }
+
+
}
Modified: axis/axis2/java/core/trunk/modules/jaxws-integration/test/org/apache/axis2/jaxws/sample/addnumbershandler/AddNumbersClientLogicalHandler3.java
URL: http://svn.apache.org/viewvc/axis/axis2/java/core/trunk/modules/jaxws-integration/test/org/apache/axis2/jaxws/sample/addnumbershandler/AddNumbersClientLogicalHandler3.java?rev=1096530&r1=1096529&r2=1096530&view=diff
==============================================================================
--- axis/axis2/java/core/trunk/modules/jaxws-integration/test/org/apache/axis2/jaxws/sample/addnumbershandler/AddNumbersClientLogicalHandler3.java (original)
+++ axis/axis2/java/core/trunk/modules/jaxws-integration/test/org/apache/axis2/jaxws/sample/addnumbershandler/AddNumbersClientLogicalHandler3.java Mon Apr 25 17:22:44 2011
@@ -56,7 +56,7 @@ public class AddNumbersClientLogicalHand
public boolean handleMessage(LogicalMessageContext messagecontext) {
Boolean outbound = (Boolean) messagecontext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
- tracker.handleFault(outbound);
+ tracker.handleMessage(outbound);
return true;
}
Modified: axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/Constants.java
URL: http://svn.apache.org/viewvc/axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/Constants.java?rev=1096530&r1=1096529&r2=1096530&view=diff
==============================================================================
--- axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/Constants.java (original)
+++ axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/Constants.java Mon Apr 25 17:22:44 2011
@@ -232,4 +232,22 @@ public interface Constants {
*/
public static final String DISPATCH_CLIENT_OUTBOUND_RESOLUTION = "jaxws.dispatch.outbound.operation.resolution.enable";
+ /**
+ * Context Property:
+ * Name: jaxws.soapfault.local.exceptions.disable
+ * Value: String "false" or "true"
+ * Default: null, which is interpreted as "false"
+ * Can be set on:
+ * - Axis Configuration, which affects all jax-ws clients
+ *
+ * Indicates if local exceptions encountered by a JAX-WS client should be turned into a SOAPFaultException
+ * and then call the appropriate JAX-WS application handlers handleFault()methods with that SOAPFault
+ * in the message. This is new behavior, which is the default behavior indicated by this property not being
+ * set or having a value of "false".
+ *
+ * The previous behavior was for local exceptions to be turned into a WebServiceException that was set
+ * on an empty response message. The appropriate JAX-WS application handers handleMessage() methods would be
+ * called with that empty message. Setting this property to "true" will revert to this behavior.
+ */
+ public static final String DISABLE_SOAPFAULT_FOR_LOCAL_EXCEPTION = "jaxws.soapfault.local.exceptions.disable";
}
Modified: axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/client/dispatch/BaseDispatch.java
URL: http://svn.apache.org/viewvc/axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/client/dispatch/BaseDispatch.java?rev=1096530&r1=1096529&r2=1096530&view=diff
==============================================================================
--- axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/client/dispatch/BaseDispatch.java (original)
+++ axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/client/dispatch/BaseDispatch.java Mon Apr 25 17:22:44 2011
@@ -838,6 +838,11 @@ public abstract class BaseDispatch<T> ex
// 4.3.2 conformance bullet 1 requires a ProtocolException here
ProtocolException pe =
MethodMarshallerUtils.createSystemException(msg.getXMLFault(), msg);
+ if (msgCtx.getLocalException() != null) {
+ // If a local exception occured, set it as the initial cause of the
+ // exception that will be returned
+ ExceptionFactory.setInitialCause(pe, msgCtx.getLocalException());
+ }
return pe;
} else if (msgCtx.getLocalException() != null) {
// use the factory, it'll throw the right thing:
Modified: axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/client/proxy/JAXWSProxyHandler.java
URL: http://svn.apache.org/viewvc/axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/client/proxy/JAXWSProxyHandler.java?rev=1096530&r1=1096529&r2=1096530&view=diff
==============================================================================
--- axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/client/proxy/JAXWSProxyHandler.java (original)
+++ axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/client/proxy/JAXWSProxyHandler.java Mon Apr 25 17:22:44 2011
@@ -581,7 +581,11 @@ public class JAXWSProxyHandler extends B
log.debug("Throwing a fault of type: " + object.getClass().getName() +
" back to the clent.");
}
-
+ if (msgCtx.getLocalException() != null) {
+ // If a local exception occured, set it as the initial cause of the
+ // exception that will be returned
+ ExceptionFactory.setInitialCause((Throwable) object, msgCtx.getLocalException());
+ }
return (Throwable)object;
} else if (msgCtx.getLocalException() != null) {
// use the factory, it'll throw the right thing:
Modified: axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/core/controller/impl/AxisInvocationController.java
URL: http://svn.apache.org/viewvc/axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/core/controller/impl/AxisInvocationController.java?rev=1096530&r1=1096529&r2=1096530&view=diff
==============================================================================
--- axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/core/controller/impl/AxisInvocationController.java (original)
+++ axis/axis2/java/core/trunk/modules/jaxws/src/org/apache/axis2/jaxws/core/controller/impl/AxisInvocationController.java Mon Apr 25 17:22:44 2011
@@ -26,6 +26,8 @@ import org.apache.axis2.addressing.Endpo
import org.apache.axis2.client.OperationClient;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
+import org.apache.axis2.description.Parameter;
+import org.apache.axis2.engine.AxisConfiguration;
import org.apache.axis2.jaxws.BindingProvider;
import org.apache.axis2.jaxws.ExceptionFactory;
import org.apache.axis2.jaxws.client.ClientUtils;
@@ -36,6 +38,8 @@ import org.apache.axis2.jaxws.client.dis
import org.apache.axis2.jaxws.core.InvocationContext;
import org.apache.axis2.jaxws.core.MessageContext;
import org.apache.axis2.jaxws.description.OperationDescription;
+import org.apache.axis2.jaxws.description.builder.MDQConstants;
+import org.apache.axis2.jaxws.handler.HandlerChainProcessor;
import org.apache.axis2.jaxws.i18n.Messages;
import org.apache.axis2.jaxws.message.Message;
import org.apache.axis2.jaxws.message.factory.MessageFactory;
@@ -140,22 +144,29 @@ public class AxisInvocationController ex
response = new MessageContext(axisResponseMsgCtx);
response.setMEPContext(request.getMEPContext());
- // If the Message object is still null, then it's possible that a
- // local AxisFault was thrown and we need to save it for later throwing
- // We do not want to create a message and go through the whole handler or
- // XMLFault processing because it's unnecessary.
- //
- // Same is true if we get a valid non-fault server response but some jaxws
- // client processing (a handler, perhaps) throws an exception.
- //
- // If the response message itself is a fault message, let it pass through.
+ // If there was a local exception caught and either there is no response message
+ // OR the response message exists but is not a fault, then set the local exception
+ // on the response and determine how to set the response message to correspond to
+ // the local exception
if ((faultexception != null) && ((response.getMessage() == null)
|| (!response.getMessage().isFault()))) {
- MessageFactory factory =
- (MessageFactory)FactoryRegistry.getFactory(MessageFactory.class);
- Message message = factory.create(request.getMessage().getProtocol());
- response.setLocalException(faultexception);
- response.setMessage(message);
+ // Unless this behavior is disabled, convert the local exception to SOAPFaultException
+ // and set it on the response message. This will also cause the JAX-WS application handler
+ // handleFault() methods to be called.
+ if (!isSOAPFaultForLocalExceptionDisabled(response)) {
+ HandlerChainProcessor.convertToFaultMessage(request.getMEPContext(), faultexception,
+ request.getMessage().getProtocol());
+ response.setLocalException(faultexception);
+ } else {
+ // The behavior was disabled, so instead of creating a SOAPFaultException
+ // just create an empty message and set the local exception on it. This will cause the
+ // JAX-WS application handler handleMessage() methods to be called with the empty message.
+ MessageFactory factory =
+ (MessageFactory)FactoryRegistry.getFactory(MessageFactory.class);
+ Message message = factory.create(request.getMessage().getProtocol());
+ response.setLocalException(faultexception);
+ response.setMessage(message);
+ }
}
// This assumes that we are on the ultimate execution thread
@@ -643,4 +654,44 @@ public class AxisInvocationController ex
ThreadContextMigratorUtil
.performContextCleanup(Constants.THREAD_CONTEXT_MIGRATOR_LIST_ID, msgContext);
}
+
+ /**
+ * Answer if generation of SOAPFaultExceptions for local Exceptions should be disabled.. The default value
+ * is "false", meaning that if a local exception is encountered, a SOAPFaultException should be generated in
+ * the message AND the appropriate JAX-WS application handlers handleFault() methods should be called with
+ * that message.
+ *
+ * @param msgContext used to get the Axis2 Configuration Context to check for the property
+ * @return false if generating SOAPFaultExceptions for local exceptions should be be enabled (default)
+ * true if it should be disabled.
+ */
+ private static boolean isSOAPFaultForLocalExceptionDisabled(MessageContext msgContext) {
+ boolean soapFaultDisabled = false;
+
+ String flagValue = null;
+ org.apache.axis2.context.MessageContext axis2MC = msgContext.getAxisMessageContext();
+ if (axis2MC != null && axis2MC.getConfigurationContext() != null
+ && axis2MC.getConfigurationContext().getAxisConfiguration() != null ) {
+ AxisConfiguration axisConfig = axis2MC.getConfigurationContext().getAxisConfiguration();
+ Parameter parameter = axisConfig.getParameter(org.apache.axis2.jaxws.Constants.DISABLE_SOAPFAULT_FOR_LOCAL_EXCEPTION);
+ if (parameter != null) {
+ flagValue = (String) parameter.getValue();
+ if (log.isDebugEnabled()) {
+ log.debug("Property set on configuration: " + org.apache.axis2.jaxws.Constants.DISABLE_SOAPFAULT_FOR_LOCAL_EXCEPTION
+ + " with value " + flagValue);
+ }
+ }
+
+ // If the property was set, check the value.
+ if (flagValue != null) {
+ if ("false".equalsIgnoreCase(flagValue)) {
+ soapFaultDisabled = false;
+ } else if ("true".equalsIgnoreCase(flagValue)) {
+ soapFaultDisabled = true;
+ }
+ }
+ }
+ return soapFaultDisabled;
+ }
+
}
Modified: axis/axis2/java/core/trunk/modules/metadata/src/org/apache/axis2/jaxws/ExceptionFactory.java
URL: http://svn.apache.org/viewvc/axis/axis2/java/core/trunk/modules/metadata/src/org/apache/axis2/jaxws/ExceptionFactory.java?rev=1096530&r1=1096529&r2=1096530&view=diff
==============================================================================
--- axis/axis2/java/core/trunk/modules/metadata/src/org/apache/axis2/jaxws/ExceptionFactory.java (original)
+++ axis/axis2/java/core/trunk/modules/metadata/src/org/apache/axis2/jaxws/ExceptionFactory.java Mon Apr 25 17:22:44 2011
@@ -323,6 +323,27 @@ public class ExceptionFactory {
pw.close();
return sw.getBuffer().toString();
}
-
+
+ /**
+ * Give a target Throwable, set the initialCause Throwable as the initial cause on the target.
+ * @param target The throwable on which to set the initial cause
+ * @param initialCause The initial cause to set on the target Throwable.
+ */
+ public static void setInitialCause(Throwable target, Throwable initialCause) {
+ if (target != null && initialCause != null) {
+ // Create a WebServiceException from the initialCause throwable. This skips over things like
+ // AxisFault as a cause. Set the result on the target throwable.
+ try {
+ WebServiceException localException = ExceptionFactory.makeWebServiceException(initialCause);
+ target.initCause(localException.getCause());
+ } catch (Throwable t) {
+ // If the cause had already been set, then it can't be set again; it throws an exception.
+ if (log.isDebugEnabled()) {
+ log.debug("Caught exception trying to set initial cause on: " + target +". Initial cause: " +
+ initialCause + ". Caught: " + t);
+ }
+ }
+ }
+ }
}