How to set JMSMessageID and JMSCorrelationID properly?

Xanathos picture Xanathos · Apr 25, 2014 · Viewed 20k times · Source

I made a java app that uses JMS to send messages to an MQ Queue. I set the message id and correlation id with the setJMSMessageId() and setJMSCorrelationId(). The messageId seems to be overwritten when the sending ends. I googled a bit, and seems that the server overwrites the messageId even when you send it.

The requirement for this app is that both messageId and correlationId have the same value when sent and when received. Isn't there anything I can do about this?

Note: I am using JDK 1.6, and a WAS 8.5 to deploy the app. This WAS communicates with a MQ Queue Manager.

Answer

rü- picture rü- · Apr 26, 2014

Message ids are reserved for the messaging system to set. You can read it and, e.g., log or even persist it, but nothing else. Esp., it's not supposed to be set by an application! The setter is there only when bridging between two messaging systems, i.e. when you receive a message from one messaging system X and forward it to a different messaging system Y. Then Y needs to be able to set the message id of that message object, even though Y has not created it, i.e. even though it's not Y's own implementation. There are several methods for this use case and it's causing a lot of confusion; it's best to just ignore them.

OTOH, correlation ids are for your application to use. A very common pattern is a request-response pair of messages, and this is the second source of confusion:

  1. An original sender A sends a message to a destination D with the reply-to header field set to a destination D' where A expects to receive the replies. The message id is set by the messaging system when A calls one of the various send methods, and A stores this message id.
  2. Then B receives the message, handles the business logic, and replies to D'. It also sets the correlation id to the message id of the message it just received. The reply message also gets a new message id from the messaging system, but that is irrelevant for this pattern.
  3. Finally A receives the reply message from D', reads the correlation id, and uses that to look up the message id it has stored in step 1.

There are a lot of other message exchange patterns, like one-request-many-replies or unsolicited messages, and the proper use of correlation ids is essential; but request-reply is by far the most common. That's why it's even suggested in the JavaDoc. Otherwise message ids have nothing to do with correlation ids. This is confusing for beginners. I even found it preferable to correlate messages with business keys instead of message ids.

Coming back to your question: as you set the correlation id before you send the message, and the message id is set by the messaging system when you send the message, there is no way in the JMS-API to make both values the same value.