Skip to content

Spring-JMS - ErrorHandler, DLQ #97

Open
@eugenevd

Description

@eugenevd

These examples are fantastic, thank you.

They do however, not have a any example showing error handling, and variations around that. Nor DLQ and variations.
Two questions that I have after some experimentation:

  1. I can define configuration class:
@Configuration
@EnableJms
public class JmsConfig {

  @Bean
  public MessageConverter jacksonJmsMessageConverter() {
    MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
    converter.setTargetType(MessageType.TEXT);
    converter.setTypeIdPropertyName("object_type"); //required : for details see https://stackoverflow.com/a/71486911
    return converter;
  }

   /*
  @Bean
  public JmsTemplate jmsTemplate(MQConnectionFactory connectionFactory) {
    JmsTemplate t = new JmsTemplate(connectionFactory); 
    t.setMessageConverter(msgConverter());
    return t;
  }
   */

  @Bean
  public MQConnectionFactory mqConnectionFactory() throws JMSException {
    MQConfigurationProperties properties = new MQConfigurationProperties();
    // Properties will be a mix of defaults, and those found in application.properties under ibm.mq
    // Here we can override any of the properties should we need to
    MQConnectionFactoryFactory mqcff = new MQConnectionFactoryFactory(properties, null);
    MQConnectionFactory mqcf = mqcff.createConnectionFactory(MQConnectionFactory.class);
    //mqcf.setMsgBatchSize();
    //mqcf.setPollingInterval();
    //mqcf.setMessageRetention();
    return mqcf;
  }

  @Bean
  public ExponentialBackOff brokerBackoff() {
    //milliseconds
    ExponentialBackOff backOff = new ExponentialBackOff(2000, 2);
    backOff.setMaxInterval(60000);
    return backOff;
  }

  @Bean
  public ErrorHandler jmsErrorHandler() {
    return new DefaultErrorHandler();
  }

  @Bean
  public JmsListenerContainerFactory<?> jmsListenerContainerFactory(MQConnectionFactory mqConnectionFactory) { //}, FixedBackOff backoff) {
    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
    factory.setConnectionFactory(mqConnectionFactory);
    factory.setMessageConverter(jacksonJmsMessageConverter());
    factory.setBackOff(brokerBackoff());
    factory.setErrorHandler(jmsErrorHandler());
    return factory;
  }

}

I can comment the bean definition for jmsListenerContainerFactory and everything that was set inside it (eg ConnectionFactory, MessageConverter), will get picked up, but not ErrorHandler? To get that to work, I have to define it as above (setErrorHandler())

@Slf4j
@Service //?
public class DefaultErrorHandler implements ErrorHandler {

  @Override
  public void handleError(Throwable t) {
    log.error("Error Message : {}", t.getMessage());
  }
}
  1. (side question) I see the example at https://www.baeldung.com/spring-jms annotates this with @Service; which I understand has a different purpose; eg things at the service layer?

  2. I've also been looking for examples and documentation that shows/explains how to config and use a DLQ
    I've looked at the configuration to be found in IBM MQ Console, and also what can be set in code. Not finding much of anything.

I'm running IBM MQ in a Docker container (as explained here: https://github.com/ibm-messaging/mq-jms-spring) with defaults, which includes three DEV queus and one DLQ. And using implementation 'com.ibm.mq:mq-jms-spring-boot-starter:2.7.5'

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions