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
The structures are transformed in two ways:
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.
Must be MQRFH_STRUC_ID (value: "RFH ") (initial value).
MQRFH_STRUC_ID_ARRAY (value: "R","F","H"," ") is also defined in the usual way.
Must be MQRFH_VERSION_2 (value: 2) (initial value).
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 of any numeric data in the portion of the message following the MQRFH2 (the next header, or the message data following this header).
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 name for the portion of the message following the MQRFH2.
MQRFH_NO_FLAGS =0. No flags set.
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) |
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:
<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:
You can use the following escape sequences, but they are not required:
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 |
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 |
The following notes relate to the mapping of JMS fields at send() or publish():
If the MQQueue persistence property is not set to JMSC.MQJMS_PER_QDEF the delivery mode value is also encoded in the MQRFH2.
These notes refer to the mapping of JMS property fields in WebSphere MQ messages:
The following notes refer to the mapping of JMS Provider specific fields into WebSphere MQ 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:
|
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:
|
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 |
|
|
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)
This section discusses the encoding of the message body itself. The encoding depends on the type of JMS message:
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.
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.
<map><elementName1 dt='datatype'>value</elementName1> <elementName2 dt='datatype'>value</elementName2>..... </map>
where:
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.
<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: