4

My question is really similar to Spring JMS(ActiveMQ) delayed delivery of messages but more correlated to the spring-boot auto configurer

I'm trying to use the jmsTemplate.setDeliveryDelay method, but it throws a java.lang.IllegalStateException: setDeliveryDelay requires JMS 2.0

I tried to find the right property from http://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html but couldn't find the broker schedulerSupport option.

Currently, my application.properties is empty, and my JmsListenerContainerFactory is defined as follows

@Bean
public JmsListenerContainerFactory<?> myFactory(ConnectionFactory connectionFactory,
                                                DefaultJmsListenerContainerFactoryConfigurer configurer) {
    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();

    configurer.configure(factory, connectionFactory);
    return factory;
}

And my pom only contains

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-activemq</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

With the spring-boot-starter-parent in 1.4.1.RELEASE

The question is: Is it possible to set the schedulerSupport to true using SpringBoot configurations?

In case it's needed, here are my Sender

public void send(String message) {
    System.out.println("Im sending this message " + message);
    jmsTemplate.setDeliveryDelay(5000);
    jmsTemplate.convertAndSend(Beans.QUEUE_NAME, message);
}

and Receiver

@JmsListener(destination = Beans.QUEUE_NAME, containerFactory = "myFactory")
public void receiveMessage(String message) {
    System.out.println("Received this message <" + message + ">");
}

thanks in advance


Update: I tried put it in the message properties, like the documentation http://activemq.apache.org/delay-and-schedule-message-delivery.html , but it doesn't work

@Bean
public MessageConverter messageConverter() {
    MessageConverter converter = new MessageConverter(){
        @Override
        public Message toMessage(Object object, Session session) throws JMSException, MessageConversionException {
            if (!(object instanceof MyPojo)) {
                throw new MessageConversionException("not agreed Pojo!");
            }
            MyPojo pojo = (MyPojo) object;

            Message message = session.createTextMessage(pojo.getMessage());
            message.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, pojo.getScheduledWait());
            return message;
        }
        @Override
        public Object fromMessage(Message message) throws JMSException, MessageConversionException {
            return message;
        }
    };
    return converter;
}
Community
  • 1
  • 1
Allan Vital
  • 376
  • 4
  • 18

2 Answers2

2

The template is trying to call the JMS 2.0 delivery delay methods but the ActiveMQ client and broker only support JMS 1.1 so you will get this error. You can use the ActiveMQ support for scheduled delivery by setting the message properties in the message using the values defined here.

It's not entirely clear how to enable the scheduler from Spring boot but my guess is that you need to provide your own Broker URI that enables it, something like:

broker:(tcp://localhost:61616)?persistent=true&useJmx=false&schedulerSupport=true
Tim Bish
  • 17,475
  • 4
  • 32
  • 42
  • Thanks for the idea. I updated the MessageConverter to use the Activemq property, but it still doesn't schedule. It delivers immediately. I updated the question with the code – Allan Vital Nov 04 '16 at 15:44
  • Make sure you have the scheduler support enabled broker side – Tim Bish Nov 04 '16 at 20:01
  • That's part of the question: how to add scheduler support in spring-boot auto configuration – Allan Vital Nov 04 '16 at 21:06
  • No clue, but if you figure that part out that should sort you out, the broker needs to have that turned on in order to supported delayed delivery. – Tim Bish Nov 04 '16 at 22:42
  • I enabled scheduler support for the embedded ActiveMQ broker using spring.activemq.broker-url=vm://embedded?broker.persistent=true&broker.schedulerSupport=true&broker.useShutdownHook=true – gwyn May 22 '22 at 19:01
1

I don't know if it's cheating, but what solved the problem for me was change the starter from activemq to artemis (https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-artemis)

Apparently, spring configures, by default, the Artemis to the JMS 2.0 interface. This way you have access to setDeliveryDelay method.

Allan Vital
  • 376
  • 4
  • 18