diff --git a/spring-integration-core/src/main/java/org/springframework/integration/gateway/GatewayProxyFactoryBean.java b/spring-integration-core/src/main/java/org/springframework/integration/gateway/GatewayProxyFactoryBean.java index e1a7f6d99d..de5b7eb6de 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/gateway/GatewayProxyFactoryBean.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/gateway/GatewayProxyFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,9 +19,8 @@ package org.springframework.integration.gateway; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; -import java.util.Arrays; +import java.lang.reflect.UndeclaredThrowableException; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.concurrent.Callable; import java.util.concurrent.Executor; @@ -269,7 +268,7 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint implements Trackab return this.invokeGatewayMethod(invocation); } catch (Throwable e) { - this.rethrowExceptionInThrowsClauseIfPossible(e, invocation.getMethod()); + this.rethrowExceptionCauseIfPossible(e, invocation.getMethod()); return null; // preceding call should always throw something } } @@ -307,11 +306,19 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint implements Trackab return (response != null) ? this.convert(response, returnType) : null; } - private void rethrowExceptionInThrowsClauseIfPossible(Throwable originalException, Method method) throws Throwable { - List> exceptionTypes = Arrays.asList(method.getExceptionTypes()); + private void rethrowExceptionCauseIfPossible(Throwable originalException, Method method) throws Throwable { + Class[] exceptionTypes = method.getExceptionTypes(); Throwable t = originalException; while (t != null) { - if (exceptionTypes.contains(t.getClass())) { + for (Class exceptionType : exceptionTypes) { + if (exceptionType.isAssignableFrom(t.getClass())) { + throw t; + } + } + if (t instanceof RuntimeException + && !(t instanceof MessagingException) + && !(t instanceof UndeclaredThrowableException) + && !(t instanceof IllegalStateException && ("Unexpected exception thrown").equals(t.getMessage()))) { throw t; } t = t.getCause(); diff --git a/spring-integration-core/src/test/java/org/springframework/integration/gateway/GatewayInvokingMessageHandlerTests.java b/spring-integration-core/src/test/java/org/springframework/integration/gateway/GatewayInvokingMessageHandlerTests.java index e4f799533d..7355c60d18 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/gateway/GatewayInvokingMessageHandlerTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/gateway/GatewayInvokingMessageHandlerTests.java @@ -104,8 +104,8 @@ public class GatewayInvokingMessageHandlerTests { gatewayWithError.process("echoWithRuntimeExceptionChannel"); Assert.fail(); } - catch (MessageHandlingException e) { - Assert.assertEquals("echoWithRuntimeExceptionChannel", e.getFailedMessage().getPayload()); + catch (SampleRuntimeException e) { + Assert.assertEquals("echoWithRuntimeExceptionChannel", e.getMessage()); } try { @@ -133,7 +133,7 @@ public class GatewayInvokingMessageHandlerTests { Assert.fail(); } catch (Exception e) { - Assert.assertTrue(e instanceof MessageHandlingException); + Assert.assertEquals(SampleRuntimeException.class, e.getClass()); } } @@ -164,27 +164,38 @@ public class GatewayInvokingMessageHandlerTests { public static class SimpleService { + public String echo(String value) { return "echo:" + value; } - public RuntimeException echoWithRuntimeException(String value) { - throw new RuntimeException(value); + + public String echoWithRuntimeException(String value) { + throw new SampleRuntimeException(value); } - public MessageHandlingException echoWithMessagingException(String value) { + public String echoWithMessagingException(String value) { throw new MessageHandlingException(new GenericMessage(value)); } - public RuntimeException echoWithErrorAsync(String value) { - throw new RuntimeException(value); + + public String echoWithErrorAsync(String value) { + throw new SampleRuntimeException(value); } } @SuppressWarnings("serial") public static class SampleCheckedException extends Exception { - public SampleCheckedException(String message){ + public SampleCheckedException(String message) { super(message); } } + + @SuppressWarnings("serial") + public static class SampleRuntimeException extends RuntimeException { + public SampleRuntimeException(String message) { + super(message); + } + } + } diff --git a/spring-integration-core/src/test/java/org/springframework/integration/gateway/InnerGatewayWithChainTests.java b/spring-integration-core/src/test/java/org/springframework/integration/gateway/InnerGatewayWithChainTests.java index c46c978a1a..d8a5ac9dc1 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/gateway/InnerGatewayWithChainTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/gateway/InnerGatewayWithChainTests.java @@ -26,7 +26,6 @@ import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.integration.Message; -import org.springframework.integration.MessageHandlingException; import org.springframework.integration.core.MessageHandler; import org.springframework.integration.core.SubscribableChannel; import org.springframework.integration.endpoint.SourcePollingChannelAdapter; @@ -84,7 +83,7 @@ public class InnerGatewayWithChainTests { } // if no error channels explicitly defined exception is rethrown - @Test(expected=MessageHandlingException.class) + @Test(expected=ArithmeticException.class) public void testGatewaysNoErrorChannel(){ testGatewayWithNoErrorChannelAAA.echo(0); }