From c06ac06bdd03729065937fb86954befcec14eb2e Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Sat, 9 Aug 2014 22:06:50 +0200 Subject: [PATCH] JmsMessagingTemplate uses local convertJmsException template method instead of generic MessagingExceptionTranslator interface This commit also turns MessagingException into a NestedRuntimeException subclass which delivers a root message that has the cause message appended to it. That's a common expectation with the use of Spring exceptions since all of our exception hierarchies have historically been designed that way. Issue: SPR-12064 Issue: SPR-12038 --- .../jms/core/JmsMessagingTemplate.java | 69 +++++++++---------- .../JmsMessagingExceptionTranslator.java | 54 --------------- .../jms/core/JmsMessagingTemplateTests.java | 11 ++- .../JmsMessagingExceptionTranslatorTests.java | 35 ---------- .../messaging/MessagingException.java | 10 +-- .../support/MessagingExceptionTranslator.java | 47 ------------- 6 files changed, 45 insertions(+), 181 deletions(-) delete mode 100644 spring-jms/src/main/java/org/springframework/jms/support/JmsMessagingExceptionTranslator.java delete mode 100644 spring-jms/src/test/java/org/springframework/jms/support/JmsMessagingExceptionTranslatorTests.java delete mode 100644 spring-messaging/src/main/java/org/springframework/messaging/support/MessagingExceptionTranslator.java diff --git a/spring-jms/src/main/java/org/springframework/jms/core/JmsMessagingTemplate.java b/spring-jms/src/main/java/org/springframework/jms/core/JmsMessagingTemplate.java index 5e2633a402d..3fc993fab16 100644 --- a/spring-jms/src/main/java/org/springframework/jms/core/JmsMessagingTemplate.java +++ b/spring-jms/src/main/java/org/springframework/jms/core/JmsMessagingTemplate.java @@ -22,8 +22,8 @@ import javax.jms.JMSException; import javax.jms.Session; import org.springframework.beans.factory.InitializingBean; +import org.springframework.jms.InvalidDestinationException; import org.springframework.jms.JmsException; -import org.springframework.jms.support.JmsMessagingExceptionTranslator; import org.springframework.jms.support.converter.MessageConverter; import org.springframework.jms.support.converter.MessagingMessageConverter; import org.springframework.jms.support.converter.SimpleMessageConverter; @@ -31,8 +31,8 @@ import org.springframework.messaging.Message; import org.springframework.messaging.MessagingException; import org.springframework.messaging.converter.MessageConversionException; import org.springframework.messaging.core.AbstractMessagingTemplate; +import org.springframework.messaging.core.DestinationResolutionException; import org.springframework.messaging.core.MessagePostProcessor; -import org.springframework.messaging.support.MessagingExceptionTranslator; import org.springframework.util.Assert; /** @@ -48,8 +48,6 @@ public class JmsMessagingTemplate extends AbstractMessagingTemplate private MessageConverter jmsMessageConverter = new MessagingMessageConverter(); - private MessagingExceptionTranslator exceptionTranslator = new JmsMessagingExceptionTranslator(); - private String defaultDestinationName; @@ -80,7 +78,7 @@ public class JmsMessagingTemplate extends AbstractMessagingTemplate * Return the configured {@link JmsTemplate}. */ public JmsTemplate getJmsTemplate() { - return jmsTemplate; + return this.jmsTemplate; } /** @@ -98,11 +96,11 @@ public class JmsMessagingTemplate extends AbstractMessagingTemplate } /** - * Set the {@link MessagingExceptionTranslator} to use. Default to - * {@link JmsMessagingExceptionTranslator}. + * Return the {@link MessageConverter} to use to convert a {@link Message} + * from the messaging to and from a {@link javax.jms.Message}. */ - public void setExceptionTranslator(MessagingExceptionTranslator exceptionTranslator) { - this.exceptionTranslator = exceptionTranslator; + public MessageConverter getJmsMessageConverter() { + return this.jmsMessageConverter; } /** @@ -124,8 +122,8 @@ public class JmsMessagingTemplate extends AbstractMessagingTemplate @Override public void afterPropertiesSet() { - Assert.notNull(this.jmsTemplate, "Property 'jmsTemplate' is required"); - Assert.notNull(this.jmsMessageConverter, "Property 'jmsMessageConverter' is required"); + Assert.notNull(getJmsTemplate(), "Property 'jmsTemplate' is required"); + Assert.notNull(getJmsMessageConverter(), "Property 'jmsMessageConverter' is required"); } @@ -295,7 +293,7 @@ public class JmsMessagingTemplate extends AbstractMessagingTemplate this.jmsTemplate.send(destination, createMessageCreator(message)); } catch (JmsException ex) { - throw translateIfNecessary(ex); + throw convertJmsException(ex); } } @@ -304,7 +302,7 @@ public class JmsMessagingTemplate extends AbstractMessagingTemplate this.jmsTemplate.send(destinationName, createMessageCreator(message)); } catch (JmsException ex) { - throw translateIfNecessary(ex); + throw convertJmsException(ex); } } @@ -312,20 +310,20 @@ public class JmsMessagingTemplate extends AbstractMessagingTemplate protected Message doReceive(Destination destination) { try { javax.jms.Message jmsMessage = this.jmsTemplate.receive(destination); - return doConvert(jmsMessage); + return convertJmsMessage(jmsMessage); } catch (JmsException ex) { - throw translateIfNecessary(ex); + throw convertJmsException(ex); } } protected Message doReceive(String destinationName) { try { javax.jms.Message jmsMessage = this.jmsTemplate.receive(destinationName); - return doConvert(jmsMessage); + return convertJmsMessage(jmsMessage); } catch (JmsException ex) { - throw translateIfNecessary(ex); + throw convertJmsException(ex); } } @@ -334,10 +332,10 @@ public class JmsMessagingTemplate extends AbstractMessagingTemplate try { javax.jms.Message jmsMessage = this.jmsTemplate.sendAndReceive( destination, createMessageCreator(requestMessage)); - return doConvert(jmsMessage); + return convertJmsMessage(jmsMessage); } catch (JmsException ex) { - throw translateIfNecessary(ex); + throw convertJmsException(ex); } } @@ -345,15 +343,15 @@ public class JmsMessagingTemplate extends AbstractMessagingTemplate try { javax.jms.Message jmsMessage = this.jmsTemplate.sendAndReceive( destinationName, createMessageCreator(requestMessage)); - return doConvert(jmsMessage); + return convertJmsMessage(jmsMessage); } catch (JmsException ex) { - throw translateIfNecessary(ex); + throw convertJmsException(ex); } } private MessagingMessageCreator createMessageCreator(Message message) { - return new MessagingMessageCreator(message, this.jmsMessageConverter); + return new MessagingMessageCreator(message, getJmsMessageConverter()); } protected String getRequiredDefaultDestinationName() { @@ -365,25 +363,29 @@ public class JmsMessagingTemplate extends AbstractMessagingTemplate return name; } - protected Message doConvert(javax.jms.Message message) { + protected Message convertJmsMessage(javax.jms.Message message) { if (message == null) { return null; } try { - return (Message) this.jmsMessageConverter.fromMessage(message); - } - catch (JMSException ex) { - throw new MessageConversionException("Could not convert '" + message + "'", ex); + return (Message) getJmsMessageConverter().fromMessage(message); } - catch (JmsException ex) { + catch (Exception ex) { throw new MessageConversionException("Could not convert '" + message + "'", ex); } } @SuppressWarnings("ThrowableResultOfMethodCallIgnored") - protected RuntimeException translateIfNecessary(RuntimeException rawException) { - MessagingException messagingException = this.exceptionTranslator.translateExceptionIfPossible(rawException); - return (messagingException != null ? messagingException : rawException); + protected MessagingException convertJmsException(JmsException ex) { + if (ex instanceof org.springframework.jms.support.destination.DestinationResolutionException || + ex instanceof InvalidDestinationException) { + return new DestinationResolutionException(ex.getMessage(), ex); + } + if (ex instanceof org.springframework.jms.support.converter.MessageConversionException) { + return new MessageConversionException(ex.getMessage(), ex); + } + // Fallback + return new MessagingException(ex.getMessage(), ex); } @@ -403,10 +405,7 @@ public class JmsMessagingTemplate extends AbstractMessagingTemplate try { return this.messageConverter.toMessage(this.message, session); } - catch (JMSException ex) { - throw new MessageConversionException("Could not convert '" + this.message + "'", ex); - } - catch (JmsException ex) { + catch (Exception ex) { throw new MessageConversionException("Could not convert '" + this.message + "'", ex); } } diff --git a/spring-jms/src/main/java/org/springframework/jms/support/JmsMessagingExceptionTranslator.java b/spring-jms/src/main/java/org/springframework/jms/support/JmsMessagingExceptionTranslator.java deleted file mode 100644 index d4052680afc..00000000000 --- a/spring-jms/src/main/java/org/springframework/jms/support/JmsMessagingExceptionTranslator.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2002-2014 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jms.support; - -import org.springframework.jms.InvalidDestinationException; -import org.springframework.jms.JmsException; -import org.springframework.jms.support.converter.MessageConversionException; -import org.springframework.jms.support.destination.DestinationResolutionException; -import org.springframework.messaging.MessagingException; -import org.springframework.messaging.support.MessagingExceptionTranslator; - -/** - * {@link MessagingExceptionTranslator} capable of translating {@link JmsException} - * instances to Spring's {@link MessagingException} hierarchy. - * - * @author Stephane Nicoll - * @since 4.1 - */ -public class JmsMessagingExceptionTranslator implements MessagingExceptionTranslator { - - @Override - public MessagingException translateExceptionIfPossible(RuntimeException ex) { - if (ex instanceof JmsException) { - return convertJmsException((JmsException) ex); - } - return null; - } - - private MessagingException convertJmsException(JmsException ex) { - if (ex instanceof DestinationResolutionException || ex instanceof InvalidDestinationException) { - return new org.springframework.messaging.core.DestinationResolutionException(ex.getMessage(), ex); - } - if (ex instanceof MessageConversionException) { - return new org.springframework.messaging.converter.MessageConversionException(ex.getMessage(), ex); - } - // Fallback - return new MessagingException(ex.getMessage(), ex); - } - -} diff --git a/spring-jms/src/test/java/org/springframework/jms/core/JmsMessagingTemplateTests.java b/spring-jms/src/test/java/org/springframework/jms/core/JmsMessagingTemplateTests.java index 1e0d539d80e..2dcd718e6cc 100644 --- a/spring-jms/src/test/java/org/springframework/jms/core/JmsMessagingTemplateTests.java +++ b/spring-jms/src/test/java/org/springframework/jms/core/JmsMessagingTemplateTests.java @@ -26,6 +26,7 @@ import javax.jms.MessageNotWriteableException; import javax.jms.Session; import javax.jms.TextMessage; +import org.hamcrest.core.StringContains; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -47,14 +48,12 @@ import org.springframework.jms.support.destination.DestinationResolutionExceptio import org.springframework.messaging.Message; import org.springframework.messaging.MessagingException; import org.springframework.messaging.converter.GenericMessageConverter; -import org.springframework.messaging.converter.MessageConversionException; import org.springframework.messaging.support.MessageBuilder; import static org.junit.Assert.*; import static org.mockito.BDDMockito.*; /** - * * @author Stephane Nicoll */ public class JmsMessagingTemplateTests { @@ -193,16 +192,16 @@ public class JmsMessagingTemplateTests { messagingTemplate.setJmsMessageConverter(new SimpleMessageConverter() { @Override public javax.jms.Message toMessage(Object object, Session session) - throws JMSException, MessageConversionException { - throw new MessageConversionException("Test exception"); + throws JMSException, org.springframework.jms.support.converter.MessageConversionException { + throw new org.springframework.jms.support.converter.MessageConversionException("Test exception"); } }); messagingTemplate.convertAndSend("myQueue", "msg to convert"); verify(jmsTemplate).send(eq("myQueue"), messageCreator.capture()); - thrown.expect(MessageConversionException.class); - thrown.expectMessage("Test exception"); + thrown.expect(org.springframework.messaging.converter.MessageConversionException.class); + thrown.expectMessage(new StringContains("Test exception")); messageCreator.getValue().createMessage(mock(Session.class)); } diff --git a/spring-jms/src/test/java/org/springframework/jms/support/JmsMessagingExceptionTranslatorTests.java b/spring-jms/src/test/java/org/springframework/jms/support/JmsMessagingExceptionTranslatorTests.java deleted file mode 100644 index ee4335a5b29..00000000000 --- a/spring-jms/src/test/java/org/springframework/jms/support/JmsMessagingExceptionTranslatorTests.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2002-2014 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.jms.support; - -import org.junit.Test; - -import static org.junit.Assert.*; - -/** - * @author Stephane Nicoll - */ -public class JmsMessagingExceptionTranslatorTests { - - private final JmsMessagingExceptionTranslator translator = new JmsMessagingExceptionTranslator(); - - @Test - public void translateNonJmsException() { - assertNull(translator.translateExceptionIfPossible(new NullPointerException())); - } - -} diff --git a/spring-messaging/src/main/java/org/springframework/messaging/MessagingException.java b/spring-messaging/src/main/java/org/springframework/messaging/MessagingException.java index 8cd33d6cced..0ef6d06e6e8 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/MessagingException.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/MessagingException.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. @@ -16,6 +16,8 @@ package org.springframework.messaging; +import org.springframework.core.NestedRuntimeException; + /** * The base exception for any failures related to messaging. * @@ -24,13 +26,13 @@ package org.springframework.messaging; * @since 4.0 */ @SuppressWarnings("serial") -public class MessagingException extends RuntimeException { +public class MessagingException extends NestedRuntimeException { private final Message failedMessage; public MessagingException(Message message) { - super(); + super(""); this.failedMessage = message; } @@ -50,7 +52,7 @@ public class MessagingException extends RuntimeException { } public MessagingException(Message message, Throwable cause) { - super(cause); + super("", cause); this.failedMessage = message; } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/support/MessagingExceptionTranslator.java b/spring-messaging/src/main/java/org/springframework/messaging/support/MessagingExceptionTranslator.java deleted file mode 100644 index 23d8152c50f..00000000000 --- a/spring-messaging/src/main/java/org/springframework/messaging/support/MessagingExceptionTranslator.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2002-2014 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.messaging.support; - -import org.springframework.messaging.MessagingException; - -/** - * Interface implemented by Spring integrations with messaging technologies - * that throw runtime exceptions, such as JMS, STOMP and AMQP. - * - *

This allows consistent usage of combined exception translation functionality, - * without forcing a single translator to understand every single possible type - * of exception. - * - * @author Stephane Nicoll - * @since 4.1 - */ -public interface MessagingExceptionTranslator { - - /** - * Translate the given runtime exception thrown by a messaging implementation - * to a corresponding exception from Spring's generic - * {@link org.springframework.messaging.MessagingException} hierarchy, if possible. - *

Do not translate exceptions that are not understood by this translator: - * for example, if resulting from user code or otherwise unrelated to messaging. - * @param ex a RuntimeException to translate - * @return the corresponding MessagingException (or {@code null} if the - * exception could not be translated, as in this case it may result from - * user code rather than from an actual messaging problem) - */ - MessagingException translateExceptionIfPossible(RuntimeException ex); - -}