IBM WebSphere MQ classes for JMS architecture
IBM® WebSphere® MQ classes for JMS, as supplied in IBM WebSphere MQ Version 7.0, and subsequent releases, contains a number of enhancements compared to previous releases. Some of these enhancements are as a result of changes to the implementation of IBM WebSphere MQ classes for JMS, and some are as a result of IBM WebSphere MQ classes for JMS exploiting changes to the underlying IBM WebSphere MQ function.
The following sections summarize the key enhancements.
A layered architecture
In previous releases of WebSphere MQ, the implementation of WebSphere MQ classes for JMS has been entirely specific to WebSphere MQ. Other IBM products that provide messaging systems have also included JMS providers, but these JMS providers have very little or nothing in common with the implementation of WebSphere MQ classes for JMS.
From WebSphere MQ V7.0, WebSphere MQ classes for JMS has a layered architecture. The top layer of code is a common layer that can be used by any IBM JMS provider. When an application calls a JMS method, any processing of the call that is not specific to a messaging system is performed by the common layer, which also provides a consistent response to the call. Any processing of the call that is specific to a messaging system is delegated to a lower layer. Figure 1 shows the layered architecture.
- To improve the consistency of behavior of the various IBM JMS providers
- To make it easier to write an bridge application between two IBM messaging systems
- To make it easier to port an application from one IBM JMS provider to another
This implementation of WebSphere MQ classes for JMS also introduces a new set of extensions to the JMS API. These extensions are known as the IBM JMS extensions. The main focus of these extensions concerns creating and configuring connection factories and destinations dynamically at run time.
An application using the IBM JMS extensions starts by creating a JmsFactoryFactory object, specifying as a parameter a constant that identifies the chosen messaging system. The application uses the JmsFactoryFactory object to create connection factories and destinations that have the correct specialized classes for the chosen messaging system.
The application can then configure the connection factories and destinations by setting their properties. The IBM JMS extensions provide a set of methods to set properties. These methods are independent of any messaging system. Each data type has its own set method, and each property is identified by a name, which is defined as a static final member of the WMQConstants class. When an application calls one of these methods, one of the parameters on the call is the name of the property, and the other parameter is the value of the property.
JmsConnectionFactory myCF;
...
myCF.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER, "JUPITER");
By contrast, an application can perform the same function by calling
the following method:MQConnectionFactory myCF;
...
myCF.setQueueManager("JUPITER");
This method is a
WebSphere MQ JMS extension and is specific
to
WebSphere MQ as the messaging system.
The use of this method therefore makes the application potentially
less easy to port to another
IBM JMS provider.The relationship between WebSphere MQ classes for JMS and WebSphere MQ classes for Java
In releases of WebSphere MQ, prior to Version 7.0, WebSphere MQ classes for JMS was implemented almost entirely as a layer of code on top of WebSphere MQ classes for Java . This arrangement has caused some confusion among application developers because setting fields or calling methods in the MQEnvironment class can cause unwanted and unexpected effects on the runtime behavior of code that is written using WebSphere MQ classes for JMS. In addition, the implementation of WebSphere MQ classes for JMS had some constraints in areas where the JMS API is not a natural fit on top of WebSphere MQ classes for Java, and these constraints have led to some issues regarding runtime performance.
From WebSphere MQ V7.0, the implementation of WebSphere MQ classes for JMS is no longer dependent on WebSphere MQ classes for Java . WebSphere MQ classes for Java and WebSphere MQ classes for JMS are now peers that use a common Java interface to the MQI. This arrangement allows more scope for optimizing performance, and means that setting fields or calling methods in the MQEnvironment class has no effect on the runtime behavior of code that is written using WebSphere MQ classes for JMS. Figure 2 shows the relationship between WebSphere MQ classes for JMS and WebSphere MQ classes for Java in previous releases of WebSphere MQ and in WebSphere MQ V7.0 and subsequent releases.
In order to maintain compatibility with earlier releases, channel exit classes written in Java can still use the WebSphere MQ classes for Java interfaces, even if the channel exit classes are called from WebSphere MQ classes for JMS. However, using the WebSphere MQ classes for Java interfaces means that your applications are still dependent on the WebSphere MQ classes for Java JAR file, com.ibm.mq.jar. If you do not want com.ibm.mq.jar in your class path, you can use the new set of interfaces in the com.ibm.mq.exits package instead.
You can now create and configure JMS administered objects with the WebSphere MQ Explorer.
Publish/subscribe messaging
WebSphere MQ V7.0, and subsequent releases, contain embedded publish/subscribe function. This function replaces WebSphere MQ Publish/Subscribe, which was supplied with WebSphere MQ V6.0.
WebSphere MQ classes for JMS applications can use the embedded publish/subscribe function, and can use it instead of using WebSphere Event Broker or WebSphere Message Broker for publish/subscribe messaging with WebSphere MQ as the transport. Configuring WebSphere MQ classes for JMS to use the new function is simpler than configuring WebSphere MQ classes for JMS to use WebSphere MQ Publish/Subscribe, WebSphere Event Broker, or WebSphere Message Broker. Administrators and application developers no longer need to manage publication queues, subscriber queues, subscription stores, and subscriber cleanup. In addition, ConnectionFactory and Topic objects have a smaller number of properties.
The embedded publish/subscribe function also provides some additional features such as retained publications and a choice of two wildcard schemes for specifying a range of topics to which an application wants to subscribe.
An application can still use a real-time connection to a broker of WebSphere Event Broker or WebSphere Message Broker for publish/subscribe messaging. This support is unchanged.
Applications using WebSphere MQ Publish/Subscribe can use the embedded publish/subscribe function without change when the queue manager to which they are connected is upgraded. Properties that are set by an application, but are not required by the embedded publish/subscribe function, are ignored.
WebSphere MQ messaging provider
- WebSphere MQ messaging provider normal mode
- WebSphere MQ messaging provider migration mode
- WebSphere MQ Version 7.0, and subsequent, queue manager in bindings or client mode, but this mode uses only those features that were available to a WebSphere MQ Version 6.0 queue manager
- WebSphere MQ Version 6.0 or earlier queue manager in client mode
If you want to connect to WebSphere Event Broker or WebSphere Message Broker using either WebSphere MQ Enterprise Transport, use the WebSphere MQ messaging provider migration mode. If you use WebSphere MQ Real-Time Transport, the WebSphere MQ messaging provider migration mode is automatically selected, because you have explicitly selected properties in the connection factory object. Connection to WebSphere Event Broker or WebSphere Message Broker using the WebSphere MQ Enterprise Transport follows the general rules for mode selection described in Rules for selecting the WebSphere MQ messaging provider mode .
Asynchronous message consumption
WebSphere MQ V7.0 and any subsequent release supports asynchronous message consumption. An application can register a callback function for a destination. When a suitable message is sent to the destination, WebSphere MQ calls the function and passes the message as a parameter. The function then processes the message asynchronously. In previous releases of WebSphere MQ, this feature was available only when using WebSphere MQ classes for JMS.
WebSphere MQ classes for JMS has been changed to exploit this new feature in WebSphere MQ V7.0 and any subsequent release. The implementation of JMS message listeners is now a more natural fit with WebSphere MQ, and WebSphere MQ classes for JMS no longer has to poll a destination to check whether a suitable message has been sent to the destination. The performance of JMS message listeners is improved as a result, particularly when an application uses multiple message listeners in a session to monitor multiple destinations. Message throughput is increased, and the time taken to deliver a message to a message listener after it has arrived at a destination is reduced.
Message driven beans (MDBs) have similar performance improvements. In addition, because of another enhancement to WebSphere MQ function, multiple MDBs that are consuming messages from the same destination now experience reduced contention on the messages.
Message selection
With the exception of selecting messages by message identifier or correlation identifier, all message selection in releases of WebSphere MQ prior to Version 7.0 was done by WebSphere MQ classes for JMS. In WebSphere MQ V7.0, and any subsequent release, all message selection is done by the queue manager.
As a result, message throughput is increased for applications that consume messages using message selection. The performance improvement is greater for an application that connects in client mode because only those messages that satisfy the selection criteria are transported over the network, and WebSphere MQ classes for JMS handles only those messages that it delivers to the application.
Sharing a communications connection
In previous releases of WebSphere MQ, if a WebSphere MQ client application connected to a queue manager more than once using the same MQI channel, each instance of the MQI channel required a separate TCP connection. In WebSphere MQ V7.0 and any subsequent release, each connection to the queue manager using the same MQI channel can share a single TCP connection. This arrangement means that fewer network resources are required and the total time taken to create multiple connections to the queue manager is reduced, particularly when using SSL because the SSL handshake takes place only once at the start of the TCP connection.
WebSphere MQ classes for JMS exploits this enhancement. For an application that connects to a queue manager in client mode, WebSphere MQ classes for JMS might create more than one connection to a queue manager using the MQI channel with the name that is specified as a property of the ConnectionFactory object. Each of these connections to the queue manager can now share a single TCP connection.
Read ahead on client connections
If an application uses a client connection to consume nonpersistent messages from a destination, the destination can be configured so that WebSphere MQ classes for JMS uses a buffer to store the messages of interest before delivering them to the application. This optimization is called read ahead and can be used by applications that consume messages synchronously by calling the receive() method, and by message listeners and MDBs, which consume messages asynchronously. Read ahead is particularly effective for destinations with a large number of messages that need to be consumed rapidly.
Read ahead does not apply to persistent messages because, if persistent messages were read into a buffer, the queue manager would no longer be able to recover the messages following a failure. However, an application that consumes messages from a destination with a mixture of persistent and nonpersistent messages can still use read ahead. The order of the messages is preserved, but the runtime benefits of read ahead apply only to the nonpersistent messages.
- If an application is consuming messages from a destination that is configured for read ahead, and the application ends for any reason, any nonpersistent messages that are currently stored in the buffer are discarded.
- If all the following conditions are true, messages sent to a queue
in a session might not be received in the order in which they were
sent:
- An application uses two message consumers in the same session to consume the messages from the queue.
- Each message consumer uses a different Destination object for the queue.
- Any or both of the Destination objects are configured for read ahead.
Sending messages
When an application sends messages to a destination, the destination can be configured so that, when the application calls send(), WebSphere MQ classes for JMS forwards the message to the queue manager and returns control back to the application without determining whether the queue manager has received the message safely. WebSphere MQ classes for JMS can work in this way only for nonpersistent messages and for persistent messages sent in a transacted session.
For persistent messages sent in a transacted session, the application ultimately determines whether the queue manager has received the messages safely when it calls commit(). For any messages sent in a session that is not transacted, the SENDCHECKCOUNT property of the ConnectionFactory object specifies how many messages are to be sent before WebSphere MQ classes for JMS checks that the queue manager has received the messages safely.
This optimization is of most benefit to an application that connects to a queue manager in client mode and needs to send a sequence of messages in rapid succession, but does not require immediate feedback from the queue manager for each message sent.
Channel exits
When called from WebSphere MQ classes for JMS, channel exit programs written in C or C++ now behave in the same way as when they are called from a Websphere MQ MQI client. The performance of channel exit classes written in Java has been improved, and you can now write channel exit classes using a new set of interfaces in the com.ibm.mq.exits package instead of using the interfaces in WebSphere MQ classes for Java.
Message properties
A JMS message consists of a set of header fields, a set of properties, and a body that contains the application data. As a minimum, a WebSphere MQ message consists of a message descriptor and the application data.
When a WebSphere MQ classes for JMS application sends a JMS message, WebSphere MQ classes for JMS maps the JMS message into a WebSphere MQ message. Some of the JMS header fields and properties are mapped into fields in the message descriptor, and some are mapped into fields in an additional WebSphere MQ header called an MQRFH2 header. When a WebSphere MQ classes for JMS application receives a JMS message, WebSphere MQ classes for JMS performs the reverse mapping.
An application that is using the MQI to receive messages from a WebSphere MQ classes for JMS application must therefore be able to handle an MQRFH2 header. If the application cannot handle an MQRFH2 header, the TARGCLIENT property of the Destination object can be set to tell WebSphere MQ classes for JMS not to include an MQRFH2 header in the WebSphere MQ messages. However, by excluding the MQRFH2 header, the information held in some of the JMS header fields and properties is lost.
Similarly, an application that is using the MQI to send messages to a WebSphere MQ classes for JMS application must include an MQRFH2 header in each message. If an MQRFH2 header is not included, WebSphere MQ classes for JMS can set only those JMS header fields and properties that can be derived from the fields in a message descriptor.
WebSphere MQ V7.0 provides some additional support for applications that use the MQI to receive messages from, and send messages to, WebSphere MQ classes for JMS applications.
- The message is delivered with a message descriptor, an MQRFH2 header that contains data derived from JMS header fields and properties, and the application data.
- The message is delivered with a message descriptor, the application data, and a set of message properties.
- The application does not have to parse the variable portion of the MQRFH2 header, which contains the JMS header field and property data encoded in an XML-like format.
- The application does not have to convert the character data in the variable portion of the MQRFH2 header.
Correspondingly, before an application calls MQPUT to send a message to a WebSphere MQ classes for JMS application, the application can use the MQSETMP call to set the values of message properties instead of constructing an MQRFH2 header.
Serviceability
WebSphere MQ classes for JMS contains a number of improvements related to serviceability:
- Tracing.
WebSphere MQ classes for JMS contains a class that an application can use to control tracing. An application can start and stop tracing, specify the required level of detail in a trace, and customize trace output in various ways..
- Logging.
WebSphere MQ classes for JMS maintains a log file, which contains messages about errors that you need to correct. The messages are written in plain text. WebSphere MQ classes for JMS contains a class that an application can use to specify the location of the log file and its maximum size.
-
First Failure Support
Technology (
FFST).
If a serious failure occurs, WebSphere MQ classes for JMS generates an FFST report in an FDC file. The FFST report contains information that IBM Service can use to diagnose the problem more quickly.
- Version information.
WebSphere MQ classes for JMS contains a class that an application can use to query the version of WebSphere MQ classes for JMS.
- Exception messages.
Exception messages have been enhanced to provide more information about the causes of errors and the actions required to correct errors.
- Application servers.
The integration of the serviceability features of WebSphere MQ classes for JMS with those of WebSphere Application Server has been improved.
MQC is replaced by MQConstants
A new package, com.ibm.mq.constants, is supplied with IBM WebSphere MQ Version 7.0. This package contains the class MQConstants, which implements a number of interfaces. MQConstants contains definitions of all the constants that were in the MQC interface and a number of new constants. The interfaces in this package closely follow the names of the constants header files used in IBM WebSphere MQ.
For example, the interface CMQC contains a constant MQOO_INPUT_SHARED; this interface and constant correspond to the header file cmqc.h and the constant MQOO_INPUT_SHARED.
com.ibm.mq.constants can be used with both IBM WebSphere MQ classes for Java and IBM WebSphere MQ classes for JMS.
MQC is still present, and has the constants it previously had. However, for any new applications, you must use the com.ibm.mq.constants package.