Handling A JMS (MQRFH2) Message in non-JMS Java Application

In the post ‘JMS (MQRFH2) Message But The User Sees Garbage‘, I wrote about how to properly view a JMS message (aka MQRFH2 message) on an MQ queue. I mentioned in the posting that non-JMS applications can be coded to deal with JMS messages. So in this posting, I’ll show you code for handling both styles of JMS messages with a non-JMS Java application.

1. JMS Message as a MQRFH2 Message
To get the JMS message as an MQRFH2 message, you need to set the MQGMO options field to include MQGMO_PROPERTIES_FORCE_MQRFH2.

MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.options = CMQC.MQGMO_PROPERTIES_FORCE_MQRFH2 + CMQC.MQGMO_FAIL_IF_QUIESCING + CMQC.MQGMO_NO_WAIT;
MQMessage receiveMsg = new MQMessage();

queue.get(receiveMsg, gmo);

if (CMQC.MQFMT_RF_HEADER_2.equals(receiveMsg.format))
{
   receiveMsg.seek(0);
   MQRFH2 rfh2 = new MQRFH2(receiveMsg);

   int strucLen = rfh2.getStrucLength();
   int encoding = rfh2.getEncoding();
   int CCSID    = rfh2.getCodedCharSetId();
   String format= rfh2.getFormat();
   int flags    = rfh2.getFlags();
   int nameValueCCSID = rfh2.getNameValueCCSID();

   String[] folderStrings = rfh2.getFolderStrings();
   for (String folder : folderStrings)
      System.out.println("Folder: "+folder);

   if (CMQC.MQFMT_STRING.equals(format))
   {
      String msgStr = receiveMsg.readStringOfByteLength(receiveMsg.getDataLength());
      System.out.println("Data: "+msgStr);
   }
   else
   {
      byte[] b = new byte[receiveMsg.getDataLength()];
      receiveMsg.readFully(b);
      System.out.println("Data: "+new String(b));
   }
}
else if (CMQC.MQFMT_STRING.equals(receiveMsg.format))
{
   String msgStr = receiveMsg.readStringOfByteLength(receiveMsg.getMessageLength());
   System.out.println("Data: "+msgStr);
}
else
{
   byte[] b = new byte[receiveMsg.getMessageLength()];
   receiveMsg.readFully(b);
   System.out.println("Data: "+new String(b));
}

2. JMS Message as an MQ Message with Named Properties
To get the JMS message as an MQ message with Named Properties, you need to set the MQGMO options field to include MQGMO_PROPERTIES_IN_HANDLE.

MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.options = CMQC.MQGMO_PROPERTIES_IN_HANDLE + CMQC.MQGMO_FAIL_IF_QUIESCING + CMQC.MQGMO_NO_WAIT;
MQMessage receiveMsg = new MQMessage();

queue.get(receiveMsg, gmo);

Enumeration<String> props = receiveMsg.getPropertyNames("%");
if (props != null)
{
   while (props.hasMoreElements())
   {
      String propName = props.nextElement();
      Object o = receiveMsg.getObjectProperty(propName);
      System.out.println("Property: Name="+propName+" : Value="+o);
   }
}

if (CMQC.MQFMT_STRING.equals(receiveMsg.format))
{
   String msgStr = receiveMsg.readStringOfByteLength(receiveMsg.getMessageLength());
   System.out.println("Data: "+msgStr);
}
else
{
   byte[] b = new byte[receiveMsg.getMessageLength()];
   receiveMsg.readFully(b);
   System.out.println("Data: "+new String(b));
}

There are many embedded message structures in MQ. Here is a list (most of them): MQCIH, MQDEAD, MQDH, MQIIH, MQRFH, MQRFH2, MQHSAP, SMQBAD, MQRMH, MQXMIT, MQTM and MQWIH.

The big thing to remember is that MQGMO option of MQGMO_PROPERTIES_* only applies to JMS messages (aka MQRFH2 messages). It does not apply to other embedded message structures. It is just one of those quirks in MQ that you just need to remember.

Regards,
Roger Lacroix
Capitalware Inc.

This entry was posted in HPE NonStop, IBM i (OS/400), IBM MQ, IBM MQ Appliance, Java, JMS, Linux, macOS (Mac OS X), Programming, Unix, Windows, z/OS.

2 Responses to Handling A JMS (MQRFH2) Message in non-JMS Java Application