Definition and usage

JMS message delivery delaying is simply sending a JMS message, but wait a defined amount of time before handling it and triggering the associated treatment. Curiously, this feature is not standardized in JMS. Most JMS providers have their own implementation to handle message delaying, but how to do when you need this feature in a portable way ?
In most case, you don’t have the choice of the JMS provider to use, since it depends of the softwares deployed in your company. Moreover, you have sometimes a different application server between development environments and production environments (for any cost or philosophical reasons).

In these cases, having a portable way to schedule JMS message can be usefull.

Principle

The solution is quite simple : we use the message selector feature included in the JMS API. Message selectors allows to consume only messages that satisfy a defined expression. In our case, the expression is simple :

_DeliverAfter_ <= System.currentTimeMillis()

where « _DeliverAfter_ » is a message property containing the value after which deliver the message.

Implementation

Using Spring

Spring is widely used and provides a very good support of JMS.
To send message, I created a subclass of Spring’s JmsTemplate which adds a timestamp parameter to each existing convertAndSend() method:

Consuming the message is simple : the MessageConsumer is created with a message selector that use the property set in the message.

Pitfalls

There’s a few pitfalls to avoid when using message delivery delaying :

Check message persistancy. You must ensure that your messages are saved in a persistent way, especially if you’re using long delays, otherwise you could lose some messages.

Use TextMessage. You must store messages in a format that could always be read, even if the version of application that send the message is different from the version that will read the message. In particular, you must avoid using ObjectMessage since its content is tightly coupled with classes used when creating the message. If your classes change before reading the message, you can encounter deserialization errors.