Xanathos
Xanathos

Reputation: 598

How to set JMSMessageID and JMSCorrelationID properly?

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.

Upvotes: 6

Views: 31653

Answers (4)

pro_cheats
pro_cheats

Reputation: 1582

Sharing my experience with the twin IDs after 4 years -

JMSMessageID is a header property set by the JMS Provider. It happens at runtime when the message is being sent to the Queue.

But JMSCorrelationID is a header property that can be set by the users to correlate the same message across different JMS Providers. Quoting from Oracle Documentation -

A JMSCorrelationID can hold one of the following:

  1. A provider-specific message ID
  2. An application-specific String
  3. A provider-native byte[] value

In some cases, an application (made up of several clients) needs to use an application-specific value for linking messages. For instance, an application may use JMSCorrelationID to hold a value referencing some external information. Application-specified values must not Start with the 'ID:' prefix; this is reserved for provider-generated message ID values.

Upvotes: 3

rü-
rü-

Reputation: 2312

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.

Upvotes: 8

Shashi
Shashi

Reputation: 15283

I set it in the application because MQ needs it

IBM MQ does not require a MessageID to be set, MQ will generate a unique MessageID on it's own. When replying, the responding application should use the MessageID (set by IBM MQ)of the incoming (aka request) message and set it as CorrelationID on the reply message. This way the requester application will be able to relate request & reply.

Upvotes: 3

Roger
Roger

Reputation: 7506

I set the message id and correlation id with the setJMSMessageId() and setJMSCorrelationId().

Whoever told you to do this, does not understand proper messaging design and should not be designing middleware infrastructure. A message id should be unique in an MQ environment. If you need to share a token/data value between 2 messaging applications then use the correlation id.

Upvotes: 2

Related Questions