Spring JMS(ActiveMQ) delayed delivery of messages
Solution 1
The comments give the answer. By default scheduled message support is disabled. You must enabled it in the broker XML configuration file as mentioned on the documentation page.
An example Broker tag with scheduler support enabled:
<broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}" schedulerSupport="true">
You must of course restart the broker in order for configuration changes to take affect. Then when you send a message you need to add the JMS headers that tell the broker what type of delay you want.
message.setIntProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, scheduledDelay);
Solution 2
Two things needs to be done to resolve this.
- By default scheduled message support is disabled. We must enabled it in the broker XML configuration file.
broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}" schedulerSupport="true">
-
Set the delay before sending the message.
public void send(Object object) { log.info("put <" + object + ">"); jmsTemplate.convertAndSend(QUEUE_NAME, object, m -> { m.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY, 10000); return m; }); }
Ayelet
Updated on June 26, 2022Comments
-
Ayelet almost 2 years
We're trying to set a delay on some JMS messages, so that a message will only be added to the queue/ received by the listener after x time. So far we've tried 2 approaches that didn't work.
1) According to the spring documentation, we can set the delivery delay on the JMSTemplate. This is the sample code we tried:
@Autowired private JmsTemplate jmsTemplate; ... long deliveryDelay = ...; this.jmsTemplate.setDeliveryDelay(deliveryDelay); this.jmsTemplate.convertAndSend( queue.getName(), event); ...
However, we get the following exception, even though our spring jms version is 4.0.5:
java.lang.IllegalStateException: setDeliveryDelay requires JMS 2.0
2) We also tried setting the delay on the message itself, but it looks like the delay was ignored, and the message was delivered immediately anyway.
@Component public class MyMessageConverter implements MessageConverter { ... @Override public Message toMessage(Object eventObject, Session session) throws JMSException, MessageConversionException { ... long deliveryDelay = ...; objectMessage.setLongProperty( ScheduledMessage.AMQ_SCHEDULED_DELAY, deliveryDelay); return objectMessage; } }
The jmsTemplate definition in the spring xml:
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"> <property name="connectionFactory" ref="cachingConnectionFactory" /> <property name="messageConverter" ref="myMessageConverter" /> <property name="sessionTransacted" value="true" /> </bean>
Does anyone has any suggestions on what the problems are / other ideas on how to achieve delayed messaging? Thanks!
-
M. Deinum almost 10 yearsYour first approach will only work for JMS 2.0 compliant JMS brokers, ActiveMQ isn't (at the moment) one of them. The second option is only going to work if you also enabled scheduling on the JMS broker side else the property will do nothing.
-
Ayelet almost 10 yearsThanks @M.Deinum. I set schedulerSupport="true" in the activemq.xml and now it works.
-
znlyj about 9 yearsThe delayed message is stored in the client side?
-
-
Tim Bish over 8 yearsThis actually depends on what broker version you are using, later releases do have an in memory scheduler store for brokers that run without persistence.
-
mech over 6 yearsCould you explain how this code snippet answers the question?
-
Melebius over 6 yearsThank you for this code snippet, which might provide some limited, immediate help. A proper explanation would greatly improve its long-term value by showing why this is a good solution to the problem and would make it more useful to future readers with other, similar questions. Please edit your answer to add some explanation, including the assumptions you’ve made.
-
Tan almost 4 yearsHey ,@Tim Bish! I am wondering where should I define this line to enable scheduler support
<broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}" schedulerSupport="true">
. I checked the documentation you shared and it doesn't says anything. My inclination isconf/activem/xml
, however, I couldn't find anything related to enablingschedulerSupport
over there. Thanks ! -
Tan almost 4 yearsCould you tell me where in
conf/activemq.xml
, I should define this line ?<broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}" schedulerSupport="true">