This section describes how the JMS message structure is mapped to a WebSphere MQ Everyplace message. It is of interest to programmers who wish to transmit messages between JMS and traditional WebSphere MQ Everyplace applications.
As described earlier, the JMS specification defines a structured message format consisting of a header, three types of property and five types of message body, while WebSphere MQ Everyplace defines a single free-format message object, MQeMsgObject. WebSphere MQ Everyplace defines some constant field names that messaging applications require, for example UniqueID, MessageID, and Priority, while applications can put data into a WebSphere MQ Everyplace message as <name, value> pairs.
To send JMS messages using WebSphere MQ Everyplace, we define a constant format for storing the information contained in a JMS message within an MQeMsgObject. This adds three top-level fields and four MQeFields objects to an MQeMsgObject, as shown in the following example.
The following sections describe the contents of these fields.
An MQeMsgObject stores data as a <name, value> pair. The field names used to map JMS message data to the MQeMsgObject are defined in com.ibm.mqe.MQe and com.ibm.mqe.jms.MQeJMSMsgFieldNames:
MQe.MQe_JMS_VERSION MQeJMSMsgFieldNames.MQe_JMS_CLASS
MQeJMSMsgFieldNames.MQe_JMS_HEADER MQeJMSMsgFieldNames.MQe_JMS_PROPERTIES MQeJMSMsgFieldNames.MQe_JMS_PS_PROPERTIES MQeJMSMsgFieldNames.MQe_JMSX_PROPERTIES MQeJMSMsgFieldNames.MQe_JMS_BODY
MQeJMSMsgFieldNames.MQe_JMS_DESTINATION MQeJMSMsgFieldNames.MQe_JMS_DELIVERYMODE MQeJMSMsgFieldNames.MQe_JMS_MESSAGEID MQeJMSMsgFieldNames.MQe_JMS_TIMESTAMP MQeJMSMsgFieldNames.MQe_JMS_CORRELATIONID MQeJMSMsgFieldNames.MQe_JMS_REPLYTO MQeJMSMsgFieldNames.MQe_JMS_REDELIVERED MQeJMSMsgFieldNames.MQe_JMS_TYPE MQeJMSMsgFieldNames.MQe_JMS_EXPIRATION MQeJMSMsgFieldNames.MQe_JMS_PRIORITY
Two <name, value> pairs holding information required for WebSphere MQ Everyplace to recreate the JMS message are added directly to the MQeMsgObject:
JMS message type | MQe.MQe_JMS_CLASS |
Bytes message | jms_bytes |
Map message | jms_map |
Null message | jms_null |
Object message | jms_object |
Stream message | jms_stream |
Text message | jms_text |
JMS Header fields are stored within an MQeMsgObject using the following rules:
The header fields that map directly to MQeMsgObject fields are:
JMS header field | MQeMsgObject defined field |
JMSTimestamp | MQe.Msg_Time |
JMSCorrelationID | MQe.Msg_CorrelID |
JMSExpiration | MQe.Msg_ExpireTime |
JMSPriority | MQe.Msg_Priority |
Two JMS header fields, JMSReplyTo and JMSMessageID, are converted prior to being stored in MQeMsgObject fields.
JMSReplyTo is split between MQe.Msg_ReplyToQMgr and MQe.Msg_ReplyToQ, while JMSMessageID is the String "ID:" followed by a 24-byte hashcode generated from a combination of MQe.Msg_OriginQMgr and MQe.Msg_Time.
The remaining four JMS header fields, JMSDeliveryMode, JMSRedelivered, and JMSType have no equivalents in WebSphere MQ Everyplace. These fields are stored within an MQeFields object in the following manner:
This MQeFields object is then stored within the MQeMsgObject as MQe.MQe_JMS_HEADER. Finally, JMSDestination is recreated when the message is received and, therefore does not need to be stored in the MQeMsgObject.
When storing JMS property fields in an MQeMsgObject, the <name, value> format used by the JMS properties corresponds very closely to the format of data in an MQeFields object:
Property type | Corresponding MQeFields object |
---|---|
Application-specific | MQe.MQe_JMS_PROPERTIES |
Standard (JMSX_name) | MQe.MQe_JMSX_PROPERTIES |
Provider-specific (JMS_provider_name) | MQe.MQe_JMS_PS_PROPERTIES |
Three MQeFields objects, corresponding to the three types of JMS property, application-specific, standard, and provider-specific are used to store the <name, value> pairs stored as JMS message properties.
These three MQeFields objects are then embedded in the MQeMsgObject with the following names:
Note that WebSphere MQ Everyplace does not currently set any provider specific properties. However, this field is used to enable WebSphere MQ Everyplace to handle JMS messages from other providers, for example WebSphere MQ.
Regardless of the JMS message type, WebSphere MQ Everyplace stores the JMS message body internally as an array of bytes. For the currently supported message types, this byte array is created as follows:
JMS message type | Conversion |
---|---|
Bytes message | ByteArrayOutputStream.toByteArray(); |
Object message | <serialized object>.toByteArray(); |
Text message | String.getBytes("UTF-8"); |
When the JMS message body is stored in an MQeMsgObject, this byte array is added directly to the MQeMsgObject with the name MQe.MQe_JMS_BODY.
The following code fragment creates a WebSphere MQ Everyplace JMS text message by adding the required fields to an MQeMsgObject:
// create an MQeMsgObject MQeMsgObject msg = new MQeMsgObject(); // set the JMS version number msg.putShort(MQe.MQe_JMS_VERSION, (short)1); // and set the type of JMS message this MQeMsgObject contains msg.putAscii(MQeJMSMsgFieldNames.MQe_JMS_CLASS, "jms_text"); // set message priority and exipry time - these are mapped to JMSPriority and JMSExpiration msg.putByte(MQe.Msg_Priority, (byte)7); msg.putLong(MQe.Msg_ExpireTime, (long)0); // store JMS header fields with no WebSphere MQ Everyplace equivalents in an MQeFields object MQeFields headerFields = new MQeFields(); headerFields.putBoolean(MQeJMSMsgFieldNames.MQe_JMS_REDELIVERED, false); headerFields.putAscii(MQeJMSMsgFieldNames.MQe_JMS_TYPE, "testMsg"); headerFields.putInt(MQeJMSMsgFieldNames.MQe_JMS_DELIVERYMODE, Message.DEFAULT_DELIVERY_MODE); msg.putFields(MQeJMSMsgFieldNames.MQe_JMS_HEADER, headerFields); // add an integer application-specific property MQeFields propField = new MQeFields(); propField.putInt("anInt", 12345); msg.putFields(MQeJMSMsgFieldNames.MQe_JMS_PROPERTIES, propField); // the provider-specific and JMSX properties are blank msg.putFields(MQeJMSMsgFieldNames.MQe_JMSX_PROPERTIES, new MQeFields()); msg.putFields(MQeJMSMsgFieldNames.MQe_JMS_PS_PROPERTIES, new MQeFields()); // finally add a text message body String msgText = "A test message to WebSphere MQ Everyplace JMS"; byte[] msgBody = msgText.getBytes("UTF8"); msg.putArrayOfByte(MQeJMSMsgFieldNames.MQe_JMS_BODY, msgBody); // send the message to a WebSphere MQ Everyplace Queue queueManager.putMessage(null, "SYSTEM.DEFAULT.LOCAL.QUEUE", msg, null, 0);
Now, we use JMS to receive the message and print it:
// first set up a QueueSession, then... Queue queue = session.createQueue ("SYSTEM.DEFAULT.LOCAL.QUEUE"); QueueReceiver receiver = session.createReceiver(queue); // receive a message Message rcvMsg = receiver.receive(1000); // and print it out System.out.println(rcvMsg.toString());
This gives:
HEADER FIELDS ----------------------------- JMSType: testMsg JMSDeliveryMode: 2 JMSExpiration: 0 JMSPriority: 7 JMSMessageID: ID:00000009524cf094000000f07c3d2266 JMSTimestamp: 1032876532326 JMSCorrelationID: null JMSDestination: null:SYSTEM.DEFAULT.LOCAL.QUEUE JMSReplyTo: null JMSRedelivered: false PROPERTY FIELDS (read only) ------------------------------ JMSXRcvTimestamp : 1032876532537 anInt : 12345 MESSAGE BODY (read only) ------------------------------------------------------------------ A test message to WebSphere MQ Everyplace JMS
Note that JMS sets some of the JMS message fields, for examole JMSMessageID, JMSXRcvTimestamp internally.
WebSphere MQ Everyplace classes for Java Message Service consist of a number of Java classes and interfaces that are based on the Sun javax.jms package of interfaces and classes. They are contained in the com.ibm.mqe.jms package. The following classes are provided:
Class | Implements |
---|---|
MQeBytesMessage | BytesMessage |
MQeConnection | Connection |
MQeConnectionFactory | ConnectionFactory |
MQeConnectionMetaData | ConnectionMetaData |
MQeDestination | Destination |
MQeJMSEnumeration | Java.util.Enumeration from QueueBrowser |
MQeJMSJNDIQueue | Queue |
MQeJMSQueue | Queue |
MQeMessage | Message |
MQeMessageConsumer | MessageConsumer |
MQeMessageProducer | MessageProducer |
MQeObjectMessage | ObjectMessage |
MQeQueueBrowser | QueueBrowser |
MQeQueueConnection | QueueConnection |
MQeJNDIQueueConnectionFactory | QueueConnectionFactory |
MQeQueueConnectionFactory | QueueConnectionFactory |
MQeQueueReceiver | QueueReceiver |
MQeQueueSender | QueueSender |
MQeQueueSession | QueueSession |
MQeSession | Session |
MQeTextMessage | TextMessage |
Note that MessageListener and ExceptionListener are implemented by applications.