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); + } + } + } + } }