Accessing IBM MQ Message data from an application using IBM MQ classes for JMS

You can access the complete IBM® MQ message data within an application using IBM MQ classes for JMS. To access all the data, the message must be a JMSBytesMessage. The body of the JMSBytesMessage includes any MQRFH2 header, any other IBM MQ headers, and the following message data.

Set the WMQ_MESSAGE_BODY property of the destination to WMQ_MESSAGE_BODY_MQ, to receive all the message body data in the JMSBytesMessage.

If WMQ_MESSAGE_BODY is set to WMQ_MESSAGE_BODY_JMS or WMQ_MESSAGE_BODY_UNSPECIFIED, the message body is returned without the JMS MQRFH2 header, and the properties of the JMSBytesMessage reflect the properties set in the RFH2.

Some applications cannot use the functions described in this topic. If an application is connected to an IBM MQ V6 queue manager, or if it has set PROVIDERVERSION to 6, the functions are not available.

Sending a message

When sending messages the destination property, WMQ_MESSAGE_BODY, takes precedence over WMQ_TARGET_CLIENT.

If WMQ_MESSAGE_BODY is set to WMQ_MESSAGE_BODY_JMS, IBM MQ classes for JMS automatically generates an MQRFH2 header based on the settings of the JMSMessage properties and header fields.

If WMQ_MESSAGE_BODY is set to WMQ_MESSAGE_BODY_MQ, no additional header is added to the message body

If WMQ_MESSAGE_BODY is set to WMQ_MESSAGE_BODY_UNSPECIFIED, IBM MQ classes for JMS sends an MQRFH2 header, unless WMQ_TARGET_CLIENT is set to WMQ_TARGET_DEST_MQ. On receive, setting WMQ_TARGET_CLIENT to WMQ_TARGET_DEST_MQ results in any MQRFH2 being removed from the message body.
Note: JMSBytesMessage and JMSTextMessage do not require an MQRFH2, whereas JMSStreamMessage, JMSMapMessage, and JMSObjectMessage do.

WMQ_MESSAGE_BODY_UNSPECIFIED is the default setting for WMQ_MESSAGE_BODY, and WMQ_TARGET_DEST_JMS is the default setting for WMQ_TARGET_CLIENT.

If you send a JMSBytesMessage, you can override the default settings for the JMS message body when the IBM MQ message is constructed. Use the following properties:
  • JMS_IBM_Format or JMS_IBM_MQMD_Format: This property specifies the format of the IBM MQ header or application payload that starts the JMS message body if there is no preceding Websphere MQ header.
  • JMS_IBM_Character_Set or JMS_IBM_MQMD_CodedCharSetId: This property specifies the CCSID of the IBM MQ header or application payload that starts the JMS message body if there is no preceding Websphere MQ header.
  • JMS_IBM_Encoding or JMS_IBM_MQMD_Encoding: This property specifies the encoding of the IBM MQ header or application payload that starts the JMS message body if there is no preceding Websphere MQ header.
If both types of property are specified, the JMS_IBM_MQMD_* properties override the corresponding JMS_IBM_* properties, as long as the destination property WMQ_MQMD_WRITE_ENABLED is set to true.
The differences in effect between setting message properties using JMS_IBM_MQMD_* and JMS_IBM_* are significant:
  1. The JMS_IBM_MQMD_* properties are specific to the IBM MQ JMS provider.
  2. The JMS_IBM_MQMD_* properties are only set in the MQMD. JMS_IBM_* properties are set in the MQMD only if the message does not have an MQRFH2 JMS header. Otherwise they are set in the JMS RFH2 header.
  3. The JMS_IBM_MQMD_* properties have no affect on the encoding of text and numbers written into a JMSMessage.

    A receiving application is likely to assume the values of MQMD.Encoding and MQMD.CodedCharSetId correspond to the encoding and character set of numbers and text in the message body. If JMS_IBM_MQMD_* properties are used, it is the responsibility of the sending application to make it so. The encoding and character set of numbers and text in the message body are set by the JMS_IBM_* properties.

    The badly coded snippet in Figure 1 sends a message encoded in character set 1208, with MQMD.CodedCharSetId set to 37.
    Figure 1. Inconsistently coded MQMD and message data
    1. Send wrongly encoded message
      
      TextMessage tmo = session.createTextMessage();
      ((MQDestination) destination).setMessageBodyStyle
                      (WMQConstants.WMQ_MESSAGE_BODY_MQ);
      ((MQDestination)destination).setMQMDWriteEnabled(true);
      tmo.setIntProperty(WMQConstants.JMS_IBM_MQMD_CODEDCHARSETID, 37);
      tmo.setIntProperty(WMQConstants.JMS_IBM_CHARACTER_SET, 1208);
      tmo.setText("String one");
      producer.send(tmo);
      
    2. Receiving the message, relying on the value of JMS_IBM_CHARACTER_SET set by the value of MQMD.CodedCharSetId:
      
      TextMessage tmi = (TextMessage) cons.receive();
      System.out.println("Message is \"" + tmi.getText() + "\"");
      
    3. Resulting output:
      
      Message is "éÈÊ'>...??>?"
      
Either of the snippets of code in Figure 2 results in a message being put to a queue or topic, with its body containing the application payload without an automatically generated MQRFH2 header being added.
Figure 2. Send a message with an MQ message body.
  1. Setting WMQ_MESSAGE_BODY_MQ:
    
    ((MQDestination) destination).setMessageBodyStyle
                    (WMQConstants.WMQ_MESSAGE_BODY_MQ);
    
  2. Setting WMQ_TARGET_DEST_MQ:
    
    ((MQDestination) destination).setMessageBodyStyle
                    (WMQConstants.WMQ_MESSAGE_BODY_UNSPECIFIED);
    ((MQDestination) destination).
                    setTargetClient(WMQConstants.WMQ_TARGET_DEST_MQ);
    

Receiving a message

If WMQ_MESSAGE_BODY is set to WMQ_MESSAGE_BODY_JMS, the inbound JMS message type and body are determined by the contents of the received Websphere MQ message. The message type and body are determined by fields in the MQRFH2 header, or in the MQMD, if there is no MQRFH2.

If WMQ_MESSAGE_BODY is set to WMQ_MESSAGE_BODY_MQ, the inbound JMS message type is JMSBytesMessage. The JMS message body is the message data returned by the underlying MQGET API call. The length of message body is the length returned by the MQGET call. The character set and encoding of the data in the message body is determined by the CodedCharSetId and Encoding fields of the MQMD. The format of the data in the message body is determined by the Format field of the MQMD

If WMQ_MESSAGE_BODY is set to WMQ_MESSAGE_BODY_UNSPECIFIED, the default value, IBM MQ classes for JMS sets it to WMQ_MESSAGE_BODY_JMS.

When you receive a JMSBytesMessage, you can decode it by reference to the following properties:
  • JMS_IBM_Format or JMS_IBM_MQMD_Format: This property specifies the format of the IBM MQ header or application payload that starts the JMS message body if there is no preceding Websphere MQ header.
  • JMS_IBM_Character_Set or JMS_IBM_MQMD_CodedCharSetId: This property specifies the CCSID of the IBM MQ header or application payload that starts the JMS message body if there is no preceding Websphere MQ header.
  • JMS_IBM_Encoding or JMS_IBM_MQMD_Encoding: This property specifies the encoding of the IBM MQ header or application payload that starts the JMS message body if there is no preceding Websphere MQ header.
The following code snippet results in a received message that is a JMSBytesMessage. Irrespective of the content of the received message and of the format field of the received MQMD, the message is a JMSBytesMessage.

  ((MQDestination)destination).setMessageBodyStyle
                              (WMQConstants.WMQ_MESSAGE_BODY_MQ);