How to set JMSXUserID in Websphere MQ using Spring JMS

Every time I work with MQ and Spring JMS I want to poke my eyes out with a dull instrument. It’s always a pain in the neck. My most recent challenge was trying to get the JMSXUserID field to flow through to the application on the other side of MQ.

First, I created a MessagePostProcessor to add the JMS header

public class MyMessagePostProcessor implements MessagePostProcessor  
	private String userId;

	public Message postProcessMessage(Message msg) throws JMSException  
		msg.setStringProperty(JmsConstants.JMS_IBM_MQMD_USERIDENTIFIER, userId);  
		msg.setStringProperty("JMSXUserID", userId);  
		return msg;  

But when I checked the queue with HermesJMS I could see that the JMSXUserID had been overwritten somewhere, so I fired up WireShark and watched for the message and confirmed that the message that was going over the wire already had the JMSXUserID field overwritten. This was a good thing - the issue was in the IBM MQ JMS client code.

Everywhere I looked online told me that the JMSXUserID field is set by the JMS provider in the ‘send’ method, and that there was little or no possibility of controlling it. Then I found [this reference]( focenter/wmqv7/v7r0/index.jsp? on the IBM site that said:

You must set the Destination object property WMQ_MQMD_WRITE_ENABLED to true for the setting of MQMD properties to have any effect

It is necessary to set WMQ_MQMD_MESSAGE_CONTEXT before setting JMS_IBM_MQMD_UserIdentifier.

However, these are properties of the Destination, to which I did not currently have access because I was using Spring’s JmsTemplate + DynamicDestinationResolver to send the message. So I extended Spring’s DynamicDestinationResolver, set the two fields I needed to and Voila! The JMSXUserID passed through.

public class MqDestinationResolver extends DynamicDestinationResolver  
	public Destination resolveDestinationName(Session session, String destinationName, boolean pubSubDomain) throws JMSException  
		MQDestination mqDest = (MQDestination)super.resolveDestinationName(session,
		destinationName, pubSubDomain);  
		mqDest.setBooleanProperty(WMQConstants.WMQ_MQMD_WRITE_ENABLED, true);  
		return dest;  

I hope this helps.

comments powered by Disqus