When I use Spring to listen to JMS messages, I receievd the above error.
I am wondering how to add an Errorhandler into the JMS listener?
When I use Spring to listen to JMS messages, I receievd the above error.
I am wondering how to add an Errorhandler into the JMS listener?
There is a property on AbstractMessageListenerContainer
:
<bean id="listener" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="errorHandler" ref="someHandler"/>
<property name="destinationName" value="someQueue"/>
<property name="connectionFactory" ref="connectionFactory"/>
</bean>
Where someHandler
is a bean implementing ErrorHandler
:
@Service
public class SomeHandler implements ErrorHandler {
@Override
public void handleError(Throwable t) {
log.error("Error in listener", t);
}
}
However note that according to the documentation:
The default behavior of this message listener [...] will log any such exception at the error level. [...] However, if error handling is necessary, then any implementation of the ErrorHandler strategy may be provided to the setErrorHandler(ErrorHandler) method.
Check out your logs, maybe the exception is already logged?
AbstractMessageListenerContainer.invokeErrorHandler()
indeed uses log.warn()
. I use @Service to autodetect the bean, of course any way to declare the error handler bean is fine. –
Ulcerate I like it short and sweet!
@Bean
JmsListenerContainerFactory<?> jmsContainerFactory(ConnectionFactory connectionFactory) {
SimpleJmsListenerContainerFactory factory = new SimpleJmsListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setErrorHandler(t -> {
log.error("Error in listener!", t);
});
return factory;
}
Without the xml configuration. I did the following in the ApplicationContext.
@Bean
JmsListenerContainerFactory<?> jmsContainerFactory(ConnectionFactory connectionFactory,
SomeHandler errorHandler) {
SimpleJmsListenerContainerFactory factory = new SimpleJmsListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setErrorHandler(errorHandler);
return factory;
}
// From Tomasz answer
@Service
public class SomeHandler implements ErrorHandler {
@Override
public void handleError(Throwable t) {
log.error("Error in listener", t);
}
}
In case when default factory used:
@Bean
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory(ConnectionFactory connectionFactory,
SomeHandler errorHandler) {
DefaultJmsListenerContainerFactory factory =
new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setErrorHandler(errorHandler);
return factory;
}
I checked the answers but No one tells about what is this error handler and why we need to set this error handler? This errorHandler is not needed for the JMSException. JMSException needs to be listened by exceptionListener as like below
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setExceptionListener(new ExceptionListener() {
@Override
public void onException(JMSException exception) {
System.out.println("JMSException is occurred " + exception);
//TODO the way you need to handle the exception
}
});
This ErrorHandler is used to be invoked in case of any uncaught exceptions thrown while processing a message.
By default, there will be no ErrorHandler so that error-level logging is the only result.
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setErrorHandler(new ErrorHandler() {
@Override
public void handleError(Throwable t) {
System.out.println("Unknown Exception is occurred " + t);
}
});
Setting up an errorHandler is a way to handle the unknown exceptions that are occurred during the message processing. but when we look at this scenario, we miss the actual message of JMS. For troubleshooting, the message will play a vital role. So My approach like below In JMSListener Method
@JmsListener(destination = "${ibm.mq.queue.response.edmonton}", containerFactory = "mqContainerFactory", concurrency = "${ibm.mq.concurrency}")
public void receiveMessage(Message message) {
try{
//MessageProcessingCode
}catch(Exception ex){
//Define a custom ErrorHandler which can take exception and message
CustomErrorHandler eh = new CustomErrorHandler();
eh.handleError(ex,message);
}
}
Please note that we will not catch the throwable because Throwable is the superclass of all errors and exceptions in Java. Error is the superclass of all errors, which are not meant to be caught by applications. Catching either Throwable or Error will also catch OutOfMemoryError and InternalError, from which an application should not attempt to recover.
© 2022 - 2024 — McMap. All rights reserved.