Mapping JMS messages onto WebSphere MQ messages

This section describes how the JMS message structure that is described in the first part of this chapter is mapped onto a WebSphere MQ message. It is of interest to programmers who wish to transmit messages between JMS and traditional WebSphere MQ applications. It is also of interest to people who wish to manipulate messages transmitted between two JMS applications - for example, in a message broker implementation.

This section does not apply when you use a direct connection to WebSphere MQ Event Broker.

WebSphere MQ messages are composed of three components:

The MQRFH2 is optional, and its inclusion in an outgoing message is governed by a flag in the JMS Destination class. You can set this flag using the WebSphere MQ JMS administration tool. Because the MQRFH2 carries JMS-specific information, always include it in the message when the sender knows that the receiving destination is a JMS application. Normally, omit the MQRFH2 when sending a message directly to a non-JMS application (WebSphere MQ Native application). This is because such an application does not expect an MQRFH2 in its WebSphere MQ message. Figure 4 shows how the structure of a JMS message is transformed to a WebSphere MQ message and back again:

Figure 4. How messages are transformed between JMS and WebSphere MQ using the MQRFH2 header

This diagram shows how messages in JMS are partly mapped and partly copied to a WebSphere MQ message when the MQRFH2 header is used. It also shows the transformation from a WebSphere MQ message to a JMS message.  The details of the transformation are in the text following the figure.

The structures are transformed in two ways:

Mapping
Where the MQMD includes a field that is equivalent to the JMS field, the JMS field is mapped onto the MQMD field. Additional MQMD fields are exposed as JMS properties, because a JMS application may need to get or set these fields when communicating with a non-JMS application.

Copying
Where there is no MQMD equivalent, a JMS header field or property is passed, possibly transformed, as a field inside the MQRFH2.

The MQRFH2 header

This section describes the MQRFH Version 2 header, which carries JMS-specific data that is associated with the message content. The MQRFH2 Version 2 is an extensible header, and can also carry additional information that is not directly associated with JMS. However, but this section covers only its use by JMS.

There are two parts of the header, a fixed portion, and a variable portion.

Fixed portion
The fixed portion is modelled on the "standard" WebSphere MQ header pattern and consists of the following fields:

StrucId (MQCHAR4)
Structure identifier.

Must be MQRFH_STRUC_ID (value: "RFH ") (initial value).

MQRFH_STRUC_ID_ARRAY (value: "R","F","H"," ") is also defined in the usual way.

Version (MQLONG)
Structure version number.

Must be MQRFH_VERSION_2 (value: 2) (initial value).

StrucLength (MQLONG)
Total length of MQRFH2, including the NameValueData fields.

The value set into StrucLength must be a multiple of 4 (the data in the NameValueData fields may be padded with space characters to achieve this).

Encoding (MQLONG)
Data encoding.

Encoding of any numeric data in the portion of the message following the MQRFH2 (the next header, or the message data following this header).

CodedCharSetId (MQLONG)
Coded character set identifier.

Representation of any character data in the portion of the message following the MQRFH2 (the next header, or the message data following this header).

Format (MQCHAR8)
Format name.

Format name for the portion of the message following the MQRFH2.

Flags (MQLONG)
Flags.

MQRFH_NO_FLAGS =0. No flags set.

NameValueCCSID (MQLONG)
The coded character set identifier (CCSID) for the NameValueData character strings contained in this header. The NameValueData may be coded in a character set that differs from the other character strings that are contained in the header (StrucID and Format).

If the NameValueCCSID is a 2-byte Unicode CCSID (1200, 13488, or 17584), the byte order of the Unicode is the same as the byte ordering of the numeric fields in the MQRFH2. (For example, Version, StrucLength, NameValueCCSID itself.)

The NameValueCCSID may take only values from the following table:

Table 17. Possible values for NameValueCCSID field

Value Meaning
1200 UCS2 open-ended
1208 UTF8
13488 UCS2 2.0 subset
17584 UCS2 2.1 subset (includes Euro symbol)

Variable Portion
The variable portion follows the fixed portion. The variable portion contains a variable number of MQRFH2 Folders. Each folder contains a variable number of elements or properties. Folders group together related properties. The MQRFH2 headers created by JMS can contain up to three folders:

The <mcd> folder
This contains properties that describe the "shape" or "format" of the message. For example the Msd property identifies the message as being Text, Bytes, Stream. Map, Object, or "Null". This folder is always present in a JMS MQRFH2.

The <jms> folder
This is used to transport JMS header fields, and JMSX properties that cannot be fully expressed in the MQMD. This folder is always present in a JMS MQRFH2.

The <usr> folder
This is used to transport any application-defined properties associated with the message. This folder is only present if the application has set some application-defined properties.

Table 18 shows a full list of property names.

Table 18. MQRFH2 folders and properties used by JMS

JMS Field Name Java type MQRFH2 Folder name Property name Type/values
JMSDestination Destination jms Dst string
JMSExpiration long jms Exp i8
JMSPriority int jms Pri i4
JMSDeliveryMode int jms Dlv i4
JMSCorrelationID String jms Cid string
JMSReplyTo Destination jms Rto string
JMSTimestamp long jms Tms i8
JMSType String mcd Type, Set, Fmt string
JMSXGroupID String jms Gid string
JMSXGroupSeq int jms Seq i4
xxx (User Defined) Any usr xxx any


mcd Msd jms_none
jms_text
jms_bytes
jms_map
jms_stream
jms_object

The syntax used to express the properties in the variable portion is as follows:

NameValueLength (MQLONG)
Length in bytes of the NameValueData string that immediately follows this length field (it does not include its own length). The value set into NameValueLength is always a multiple of 4 (the NameValueData field is padded with space characters to achieve this).

NameValueData (MQCHARn)
A single character string, whose length in bytes is given by the preceding NameValueLength field. It contains a "folder" holding a sequence of "properties". Each property is a "name/type/value" triplet, contained within an XML element whose name is the folder name, as follows:
 <foldername> triplet1 triplet2 .....   tripletn </foldername>

The closing </foldername> tag can be followed by spaces as padding characters. Each triplet is encoded using an XML-like syntax:

   <name dt='datatype'>value</name>

The dt='datatype' element is optional and is omitted for many properties, because their datatype is predefined. If it is included, one or more space characters must be included before the dt= tag.

name is the name of the property - see Table 18.

datatype must match, after folding, one of the literal Datatype values in Table 19.

value is a string representation of the value to be conveyed, using the Definitions inTable 19.

A null value is encoded using the following syntax:

<name dt="DataType" xsi:nil="true"></name>		

Note that xsi:nil="false" should not be used.

Table 19. Property datatype values and definitions

Datatype value Definition
string Any sequence of characters excluding < and &
boolean The character 0 or 1 (1 = "true")
bin.hex Hexadecimal digits representing octets
i1 A number, expressed using digits 0..9, with optional sign (no fractions or exponent). Must lie in the range -128 to 127 inclusive
i2 A number, expressed using digits 0..9, with optional sign (no fractions or exponent). Must lie in the range -32768 to 32767 inclusive
i4 A number, expressed using digits 0..9, with optional sign (no fractions or exponent). Must lie in the range -2147483648 to 2147483647 inclusive
i8 A number, expressed using digits 0..9, with optional sign (no fractions or exponent). Must lie in the range -9223372036854775808 to 92233720368547750807 inclusive
int A number, expressed using digits 0..9, with optional sign (no fractions or exponent). Must lie in the same range as 'i8'. This can be used in place of one of the 'i*' types if the sender does not wish to associate a particular precision with the property
r4 Floating point number, magnitude <= 3.40282347E+38, >= 1.175E-37 expressed using digits 0..9, optional sign, optional fractional digits, optional exponent
r8 Floating point number, magnitude <= 1.7976931348623E+308, >= 2.225E-307 expressed using digits 0..9, optional sign, optional fractional digits, optional exponent

A string value may contain spaces. You must use the following escape sequences in a string value:

&amp; for the & character
&lt; for the < character

You can use the following escape sequences, but they are not required:

&gt; for the > character
&apos; for the ' character
&quot; for the " character

JMS fields and properties with corresponding MQMD fields

Table 20 lists the JMS header fields and Table 21 lists the JMS properties that are mapped directly to MQMD fields. Table 22 lists the provider specific properties and the MQMD fields that they are mapped to.

Table 20. JMS header fields mapping to MQMD fields

JMS header field Java type MQMD field C type
JMSDeliveryMode int Persistence MQLONG
JMSExpiration long Expiry MQLONG
JMSPriority int Priority MQLONG
JMSMessageID String MessageID MQBYTE24
JMSTimestamp long PutDate
PutTime
MQCHAR8
MQCHAR8
JMSCorrelationID String CorrelId MQBYTE24

Table 21. JMS properties mapping to MQMD fields

JMS property Java type MQMD field C type
JMSXUserID String UserIdentifier MQCHAR12
JMSXAppID String PutApplName MQCHAR28
JMSXDeliveryCount int BackoutCount MQLONG
JMSXGroupID String GroupId MQBYTE24
JMSXGroupSeq int MsgSeqNumber MQLONG

Table 22. JMS provider specific properties mapping to MQMD fields

JMS provider specific property Java type MQMD field C type
JMS_IBM_Report_Exception int Report MQLONG
JMS_IBM_Report_Expiration int Report MQLONG
JMS_IBM_Report_COA int Report MQLONG
JMS_IBM_Report_COD int Report MQLONG
JMS_IBM_Report_PAN int Report MQLONG
JMS_IBM_Report_NAN int Report MQLONG
JMS_IBM_Report_Pass_Msg_ID int Report MQLONG
JMS_IBM_Report_Pass_Correl_ID int Report MQLONG
JMS_IBM_Report_Discard_Msg int Report MQLONG
JMS_IBM_MsgType int MsgType MQLONG
JMS_IBM_Feedback int Feedback MQLONG
JMS_IBM_Format String Format MQCHAR8
JMS_IBM_PutApplType int PutApplType MQLONG
JMS_IBM_Encoding int Encoding MQLONG
JMS_IBM_Character_Set String CodedCharacterSetId MQLONG
JMS_IBM_PutDate String PutDate MQCHAR8
JMS_IBM_PutTime String PutTime MQCHAR8
JMS_IBM_Last_Msg_In_Group boolean MsgFlags MQLONG

Mapping JMS fields onto WebSphere MQ fields (outgoing messages)

Table 23 shows how the JMS header fields are mapped into MQMD/RFH2 fields at send() or publish() time. Table 24 shows how JMS properties and Table 25 shows how JMS provider specific properties are mapped to MQMD fields at send() or publish() time,

For fields marked "Set by Message Object", the value transmitted is the value held in the JMS message immediately before the send() or publish() operation. The value in the JMS Message is left unchanged by the operation.

For fields marked "Set by Send Method", a value is assigned when the send() or publish() is performed (any value held in the JMS Message is ignored). The value in the JMS message is updated to show the value used.

Fields marked as "Receive-only" are not transmitted and are left unchanged in the message by send() or publish().

Table 23. Outgoing message field mapping

JMS header field name MQMD field used for transmission Header Set by
JMSDestination
MQRFH2 Send Method
JMSDeliveryMode Persistence MQRFH2 Send Method
JMSExpiration Expiry MQRFH2 Send Method
JMSPriority Priority MQRFH2 Send Method
JMSMessageID MessageID
Send Method
JMSTimestamp PutDate/PutTime
Send Method
JMSCorrelationID CorrelId MQRFH2 Message Object
JMSReplyTo ReplyToQ/ReplyToQMgr MQRFH2 Message Object
JMSType
MQRFH2 Message Object
JMSRedelivered

Receive-only

Table 24. Outgoing message JMS property mapping

JMS property name MQMD field used for transmision Header Set by
JMSXUserID UserIdentifier
Send Method
JMSXAppID PutApplName
Send Method
JMSXDeliveryCount

Receive-only
JMSXGroupID GroupId MQRFH2 Message Object
JMSXGroupSeq MsgSeqNumber MQRFH2 Message Object

Table 25. Outgoing message JMS provider specific property mapping

JMS provider specific property name MQMD field used for transmission Header Set by
JMS_IBM_Report_Exception Report
Message Object
JMS_IBM_Report_Expiration Report
Message Object
JMS_IBM_Report_COA/COD Report
Message Object
JMS_IBM_Report_NAN/PAN Report
Message Object
JMS_IBM_Report_Pass_Msg_ID Report
Message Object
JMS_IBM_Report_Pass_Correl_ID Report
Message Object
JMS_IBM_Report_Discard_Msg Report
Message Object
JMS_IBM_MsgType MsgType
Message Object
JMS_IBM_Feedback Feedback
Message Object
JMS_IBM_Format Format
Message Object
JMS_IBM_PutApplType PutApplType
Send Method
JMS_IBM_Encoding Encoding
Message Object
JMS_IBM_Character_Set CodedCharacterSetId
Message Object
JMS_IBM_PutDate PutDate
Send Method
JMS_IBM_PutTime PutTime
Send Method
JMS_IBM_Last_Msg_In_Group MsgFlags
Message Object

Mapping JMS header fields at send() or publish()

The following notes relate to the mapping of JMS fields at send() or publish():

Mapping JMS property fields

These notes refer to the mapping of JMS property fields in WebSphere MQ messages:

Mapping JMS provider-specific fields

The following notes refer to the mapping of JMS Provider specific fields into WebSphere MQ messages:

Mapping WebSphere MQ fields onto JMS fields (incoming messages)

Table 26 shows how JMS header fields and Table 27 shows how JMS property fields are mapped into MQMD/MQRFH2 fields at send() or publish() time. Table 28 shows how JMS provider specific properties are mapped.

Table 26. Incoming message JMS header field mapping

JMS header field name MQMD field retrieved from MQRFH2 field retrieved from
JMSDestination
jms.Dst
JMSDeliveryMode Persistence(JMSDLVN) jms.Dlv(JMSDLVN)
JMSExpiration
jms.Exp
JMSPriority Priority
JMSMessageID MessageID
JMSTimestamp PutDate(JMSDLVN)
PutTime(JMSDLVN)
jms.Tms(JMSDLVN)
JMSCorrelationID CorrelId(JMSDLVN) jms.Cid(JMSDLVN)
JMSReplyTo ReplyToQ(JMSDLVN)
ReplyToQMgr(JMSDLVN)
jms.Rto(JMSDLVN)
JMSType
mcd.Type, mcd.Set, mcd.Fmt
JMSRedelivered BackoutCount

Notes:

  1. For properties that can have values retrieved from the MQRFH2 or the MQMD, if both are available, the setting in the MQRFH2 is used.


Table 27. Incoming message property mapping

JMS property name MQMD field retrieved from MQRFH2 field retrieved from
JMSXUserID UserIdentifier
JMSXAppID PutApplName
JMSXDeliveryCount BackoutCount
JMSXGroupID GroupId(JMSDN2) jms.Gid(JMSDN2)
JMSXGroupSeq MsgSeqNumber(JMSDN2) jms.Seq(JMSDN2)

Notes:

  1. For properties that can have values retrieved from the MQRFH2 or the MQMD, if both are available, the setting in the MQRFH2 is used.


Table 28. Incoming message provider specific JMS property mapping

JMS property name MQMD field retrieved from MQRFH2 field retrieved from
JMS_IBM_Report_Exception Report
JMS_IBM_Report_Expiration Report
JMS_IBM_Report_COA Report
JMS_IBM_Report_COD Report
JMS_IBM_Report_PAN Report
JMS_IBM_Report_NAN Report
JMS_IBM_Report_ Pass_Msg_ID Report
JMS_IBM_Report_Pass_Correl_ID Report
JMS_IBM_Report_Discard_Msg Report
JMS_IBM_MsgType MsgType
JMS_IBM_Feedback Feedback
JMS_IBM_Format Format
JMS_IBM_PutApplType PutApplType
JMS_IBM_Encoding 1 Encoding
JMS_IBM_Character_Set 1 CodedCharacterSetId
JMS_IBM_PutDate PutDate
JMS_IBM_PutTime PutTime
JMS_IBM_Last_Msg_In_Group MsgFlags
  1. Only set if the incoming message is a Bytes Message.

Mapping JMS to a native WebSphere MQ application

This section describes what happens if you send a message from a JMS Client application to a traditional WebSphere MQ application which has no knowledge of MQRFH2 headers. Figure 5 is a diagram of the mapping.

The administrator indicates that the JMS Client is communicating with such an application by setting the WebSphere MQ Destination's TargetClient value to JMSC.MQJMS_CLIENT_NONJMS_MQ. This indicates that no MQRFH2 field is to be produced. Note that if this is not done, the receiving application must be able to handle the MQRFH2 field.

The mapping from JMS to MQMD targeted at a native WebSphere MQ application is the same as mapping from JMS to MQMD targeted at a true JMS client. If JMS receives a WebSphere MQ message with the MQMD Format field set to other than MQFMT_RFH2, we know that we are receiving data from a non-JMS application. If the Format is MQFMT_STRING, the message is received as a JMS Text Message. Otherwise, it is received as a JMS Bytes message. Because there is no MQRFH2, only those JMS properties that are transmitted in the MQMD can be restored.

Figure 5. How JMS messages are transformed to WebSphere MQ messages (no MQRFH2 header)

The diagram shows how a JMS message is mapped and copied to a WebSphere MQ message when no MQRFH2 header is used. The reverse transformation is also shown.  In this case, JMS header fields and properties are mapped to corresponding fields in the MQMD, and vice versa.

Message body

This section discusses the encoding of the message body itself. The encoding depends on the type of JMS message:

ObjectMessage
is an object serialized by the Java Runtime in the normal way.

TextMessage
is an encoded string. For an outgoing message, the string is encoded in the character set given by the Destination object. This defaults to UTF8 encoding (the UTF8 encoding starts with the first character of the message - there is no length field at the start). It is, however, possible to specify any other character set supported by WebSphere MQ Java. Such character sets are used mainly when you send a message to a non-JMS application.

If the character set is a double-byte set (including UTF16), the Destination object's integer encoding specification determines the order of the bytes.

An incoming message is interpreted using the character set and encoding that are specified in the message itself. These specifications are in the rightmost WebSphere MQ header (or MQMD if there are no headers). For JMS messages, the rightmost header will usually be the MQRFH2.

BytesMessage
is, by default, a sequence of bytes as defined by the JMS 1.0.2 specification, and associated Java documentation.

For an outgoing message that was assembled by the application itself, the Destination object's encoding property may be used to override the encodings of integer and floating point fields contained in the message. For example, you can request that floating point values are stored in S/390 rather than IEEE format).

An incoming message is interpreted using the numeric encoding specified in the message itself. This specification is in the rightmost WebSphere MQ header (or MQMD if there are no headers). For JMS messages, the rightmost header will usually be the MQRFH2.

If a BytesMessage is received, and is resent without modification, its body is transmitted byte for byte, as it was received. The Destination object's encoding property has no effect on the body. The only string-like entity that can be sent explicitly in a BytesMessage is a UTF8 string. This is encoded in Java UTF8 format, and starts with a 2-byte length field. The Destination object's character set property has no effect on the encoding of an outgoing BytesMessage. The character set value in an incoming WebSphere MQ message has no effect on the interpretation of that message as a JMS BytesMessage.

Non-Java applications are unlikely to recognize the Java UTF8 encoding. Therefore, for a JMS application to send a BytesMessage that contains text data, the application itself must convert its strings to byte arrays, and write these byte arrays into the BytesMessage.

MapMessage
is a string containing a set of XML name/type/value triplets, encoded as:
<map><elementName1 dt='datatype'>value</elementName1>
<elementName2 dt='datatype'>value</elementName2>.....
</map>

where:

datatype can take one of the values described in Table 19.
string is the default datatype, so dt='string' is omitted.

The character set used to encode or interpret the XML string that makes up the MapMessage body is determined following the rules that apply to a TextMessage.

StreamMessage
is like a map, but without element names:
<stream><elt dt='datatype'>value</elt>
<elt dt='datatype'>value</elt>.....</stream>

Every element is sent using the same tagname (elt). The default type is string, so dt='string' is omitted for string elements.

The character set used to encode or interpret the XML string that makes up the StreamMessage body is determined following the rules that apply to a TextMessage.

The MQRFH2.format field is set as follows:

MQFMT_NONE
for ObjectMessage, BytesMessage, or messages with no body.

MQFMT_STRING
for TextMessage, StreamMessage, or MapMessage.


© IBM Corporation 1997, 2002. All Rights Reserved