Avoid JMSException in listener execution
This commit avoids throwing JMSException from the listener execution as this is not allowed per spec. Our SessionAwareMessageListener gives a callback that can throw JMSException and we have "abused" it so far. Typical message processing goes in those 3 steps: * Unmarshall the javax.jms.Message to the requested type * Invoke the actual user method (including processing of method arguments) * Send a reply message, if any Those three steps have been harmonized so that they don't throw a JMSException anymore. For the later case, introduced ReplyFailureException as a general exception indicating the reply message could not have been sent. Issue: SPR-11778
This commit is contained in:
@@ -46,6 +46,7 @@ import org.springframework.jms.StubTextMessage;
|
||||
import org.springframework.jms.listener.DefaultMessageListenerContainer;
|
||||
import org.springframework.jms.listener.MessageListenerContainer;
|
||||
import org.springframework.jms.listener.SimpleMessageListenerContainer;
|
||||
import org.springframework.jms.listener.adapter.ReplyFailureException;
|
||||
import org.springframework.jms.listener.adapter.ListenerExecutionFailedException;
|
||||
import org.springframework.jms.listener.adapter.MessagingMessageListenerAdapter;
|
||||
import org.springframework.jms.support.JmsMessageHeaderAccessor;
|
||||
@@ -275,7 +276,7 @@ public class MethodJmsListenerEndpointTests {
|
||||
Session session = mock(Session.class);
|
||||
given(session.createTextMessage("content")).willReturn(reply);
|
||||
|
||||
thrown.expect(ListenerExecutionFailedException.class);
|
||||
thrown.expect(ReplyFailureException.class);
|
||||
thrown.expectCause(Matchers.isA(InvalidDestinationException.class));
|
||||
listener.onMessage(createSimpleJmsTextMessage("content"), session);
|
||||
}
|
||||
|
||||
@@ -306,8 +306,10 @@ public class MessageListenerAdapterTests {
|
||||
};
|
||||
try {
|
||||
adapter.onMessage(sentTextMessage, session);
|
||||
fail("expected InvalidDestinationException");
|
||||
} catch(InvalidDestinationException ex) { /* expected */ }
|
||||
fail("expected CouldNotSendReplyException with InvalidDestinationException");
|
||||
} catch(ReplyFailureException ex) {
|
||||
assertEquals(InvalidDestinationException.class, ex.getCause().getClass());
|
||||
}
|
||||
|
||||
verify(responseTextMessage).setJMSCorrelationID(CORRELATION_ID);
|
||||
verify(delegate).handleMessage(sentTextMessage);
|
||||
@@ -342,8 +344,10 @@ public class MessageListenerAdapterTests {
|
||||
};
|
||||
try {
|
||||
adapter.onMessage(sentTextMessage, session);
|
||||
fail("expected JMSException");
|
||||
} catch(JMSException ex) { /* expected */ }
|
||||
fail("expected CouldNotSendReplyException with JMSException");
|
||||
} catch(ReplyFailureException ex) {
|
||||
assertEquals(JMSException.class, ex.getCause().getClass());
|
||||
}
|
||||
|
||||
verify(responseTextMessage).setJMSCorrelationID(CORRELATION_ID);
|
||||
verify(messageProducer).close();
|
||||
@@ -420,8 +424,10 @@ public class MessageListenerAdapterTests {
|
||||
adapter.setMessageConverter(null);
|
||||
try {
|
||||
adapter.onMessage(sentTextMessage, session);
|
||||
fail("expected MessageConversionException");
|
||||
} catch(MessageConversionException ex) { /* expected */ }
|
||||
fail("expected CouldNotSendReplyException with MessageConversionException");
|
||||
} catch(ReplyFailureException ex) {
|
||||
assertEquals(MessageConversionException.class, ex.getCause().getClass());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -34,6 +34,7 @@ import org.springframework.jms.StubTextMessage;
|
||||
import org.springframework.jms.config.DefaultJmsHandlerMethodFactory;
|
||||
import org.springframework.jms.support.converter.JmsHeaders;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.converter.MessageConversionException;
|
||||
import org.springframework.messaging.support.MessageBuilder;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
@@ -63,7 +64,8 @@ public class MessagingMessageListenerAdapterTests {
|
||||
|
||||
Session session = mock(Session.class);
|
||||
given(session.createTextMessage("Response")).willReturn(new StubTextMessage("Response"));
|
||||
javax.jms.Message replyMessage = getSimpleInstance().buildMessage(session, result);
|
||||
MessagingMessageListenerAdapter listener = getSimpleInstance("echo", Message.class);
|
||||
javax.jms.Message replyMessage = listener.buildMessage(session, result);
|
||||
|
||||
verify(session).createTextMessage("Response");
|
||||
assertNotNull("reply should never be null", replyMessage);
|
||||
@@ -73,8 +75,45 @@ public class MessagingMessageListenerAdapterTests {
|
||||
assertEquals("replyTo header not copied", replyTo, replyMessage.getJMSReplyTo());
|
||||
}
|
||||
|
||||
protected MessagingMessageListenerAdapter getSimpleInstance() {
|
||||
Method m = ReflectionUtils.findMethod(SampleBean.class, "echo", Message.class);
|
||||
@Test
|
||||
public void exceptionInListener() {
|
||||
javax.jms.Message message = new StubTextMessage("foo");
|
||||
Session session = mock(Session.class);
|
||||
MessagingMessageListenerAdapter listener = getSimpleInstance("fail", String.class);
|
||||
|
||||
try {
|
||||
listener.onMessage(message, session);
|
||||
fail("Should have thrown an exception");
|
||||
}
|
||||
catch (JMSException e) {
|
||||
fail("Should not have thrown a JMS exception");
|
||||
}
|
||||
catch (ListenerExecutionFailedException e) {
|
||||
assertEquals(IllegalArgumentException.class, e.getCause().getClass());
|
||||
assertEquals("Expected test exception", e.getCause().getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void exceptionInInvocation() {
|
||||
javax.jms.Message message = new StubTextMessage("foo");
|
||||
Session session = mock(Session.class);
|
||||
MessagingMessageListenerAdapter listener = getSimpleInstance("wrongParam", Integer.class);
|
||||
|
||||
try {
|
||||
listener.onMessage(message, session);
|
||||
fail("Should have thrown an exception");
|
||||
}
|
||||
catch (JMSException e) {
|
||||
fail("Should not have thrown a JMS exception");
|
||||
}
|
||||
catch (ListenerExecutionFailedException e) {
|
||||
assertEquals(MessageConversionException.class, e.getCause().getClass());
|
||||
}
|
||||
}
|
||||
|
||||
protected MessagingMessageListenerAdapter getSimpleInstance(String methodName, Class... parameterTypes) {
|
||||
Method m = ReflectionUtils.findMethod(SampleBean.class, methodName, parameterTypes);
|
||||
return createInstance(m);
|
||||
}
|
||||
|
||||
@@ -97,5 +136,13 @@ public class MessagingMessageListenerAdapterTests {
|
||||
.setHeader(JmsHeaders.TYPE, "reply")
|
||||
.build();
|
||||
}
|
||||
|
||||
public void fail(String input) {
|
||||
throw new IllegalArgumentException("Expected test exception");
|
||||
}
|
||||
|
||||
public void wrongParam(Integer i) {
|
||||
throw new IllegalArgumentException("Should not have been called");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user