Sun Java System Message Queue 4.1 Release Notes

What’s New in the 4.0 Release

Message Queue 4.0 includes the following new features:

These are described in the following subsections.


Caution – Caution –

One of the more minor but potentially disruptive changes introduced with version 4.0 is the deprecation of the command-line option to specify a password. Henceforth, you must store all passwords in a file as described in Deprecated Password Option.


Interface Changes to the C API and C Client Runtime

Version 4.0 of Message Queue adds two new properties which will be set on all messages that have been placed on the dead message queue.

Interface Changes to the Java API and the Java Client Runtime

Version 4.0 of Message Queue adds two new properties which will be set on all messages that have been placed on the dead message queue.

Displaying Information About the Persistent Store

The query subcommand was added to the imqdbmgr command. Use this subcommand to display information about the persistent store, including the store version, the database user, and whether the database tables have been created.

The following is an example of the information displayed by the command.


imqdbmgr query

[04/Oct/2005:15:30:20 PDT] Using plugged-in persistent store:
        version=400
        brokerid=Mozart1756
        database connection url=jdbc:oracle:thin:@Xhome:1521:mqdb
        database user=scott
Running in standalone mode.
Database tables have already been created.

Persistent Store Format Changes

Version 3.7 UR1 of Message Queue introduced two changes to the persistent store format to improve performance. One change is to the file store, the other is to the JDBC store.

Because these changes impact store compatibility, the store version for both the file store and the JDBC store was changed from 350 to 370 in version 3.7 UR1 of Message Queue.

Version 4.0 of Message Queue introduced changes to the JDBC store for optimization and to support future enhancements. For this reason the JDBC store version was increased to 400. Note that in Version 4.0, the file-based persistent store version remains 370 because no changes were made to it.

Message Queue 4.0 supports automatic conversion of the persistent store to the newest versions of the file-based and JDBC persistent stores. The first time imqbrokerd starts, if the utility detects an older store it will migrate the store to the new format, leaving the old store behind.

If you should need to roll back this upgrade, you can uninstall Message Queue 4.0 and then reinstall the version you were previously running. Since the older copy of the store is left intact, the broker can run with the older copy of the store.

Broker Administration

The Command utility (imqcmd) has added a subcommand and several options that allow administrators to quiesce the broker, to shutdown the broker after a specified interval, to destroy a connection, or to set java system properties (for example, connection related properties.)

For complete information about the syntax of the imqcmd command, see Chapter 13, Command Line Reference, in Sun Java System Message Queue 4.1 Administration Guide.

JDBC Persistence Support

Apache Derby Version 10.1.1 is now supported as a JDBC-compliant persistent store provider.

SSL Support

Starting with release 4.0, the default value for the client connection factory property imqSSLIsHostTrusted is false. If your application depends on the prior default value of true, you need to reconfigure and to set the property explicitly to true.

You might choose to trust the host when the broker is configured to use self-signed certificates. In this case, in addition to specifying that the connection should use an SSL-based connection service (using the imqConnectionType property), you should set the imqSSLIsHostTrusted property to true.

For example, to run client applications securely when the broker uses self-signed certificates, use a command like the following.

java -DimqConnectionType=TLS 
      -DimqSSLIsHostTrusted=true <ClientAppName>

To run the administration tool imqcmd securely when the broker uses self-signed certificates, use a command like the following.

imqcmd list svc -secure -DimqSSLIsHostTrusted=true

JMX Support

A new API has been added for configuring and monitoring Message Queue brokers in conformance with the Java Management Extensions (JMX) specification. Using this API, you can configure and monitor broker functions programmatically from within a Message Queue client application. In earlier versions of Message Queue, these functions were accessible only from the command line or the Administration Console.

The API consists of a set of JMX Managed Beans (MBeans) for managing the following Message Queue–related resources:

These MBeans provide attributes and operations for synchronously polling and manipulating the state of the underlying resources, as well as notifications that allow a client application to listen for and respond asynchronously to state changes as they occur. Using the JMX API, client applications can perform configuration and monitoring tasks like the following:

For an introduction to the JMX API and for complete reference information, see the Sun Java System Message Queue 4.1 Developer’s Guide for JMX Clients.

Broker Support: JMX-Related Properties

Several new broker properties have been added to support the JMX API (see Table 1–3). None of these properties can be set from the command line with the Message Queue Command utility (imqcmd). Instead, they can either be set with the -D option of the Broker utility (imqbrokerd) or edited by hand in the broker's instance configuration file (config.properties). In addition, some of these properties (imq.jmx.rmiregistry.start, imq.jmx.rmiregistry.use, imq.jmx.rmiregistry.port) can be set with the new Broker utility options described in Table 1–4. The table lists each option, specifies its type, and describes its use.

Table 1–3 New Broker Properties for JMX Support

Property 

Type 

Description 

imq.jmx.rmiregistry.start

Boolean

Specifies whether to start RMI registry at broker startup.

If true, the broker will start an RMI registry at the port specified by imq.jmx.rmiregistry.port and use it to store the RMI stub for JMX connectors. Note that the value of imq.jmx.rmiregistry.use is ignored in this case.

Default value: false

imq.jmx.rmiregistry.use

Boolean

Specifies whether to use an external RMI registry.

Applies only if imq.jmx.rmiregistry.start is false.

If true, the broker will use an external RMI registry at the port specified by imq.jmx.rmiregistry.port to store the RMI stub for JMX connectors. The external RMI registry must already be running at broker startup.

Default value: false

imq.jmx.rmiregistry.port

Integer

Port number of RMI registry

Applies only if imq.jmx.rmiregistry.start or imq.jmx.rmiregistry.use is true. JMX connectors can then be configured to use the RMI registry by including this port number in the URL path of their JMX service URLs.

Default value: 1099

imq.jmx.connector.list

String

Names of preconfigured JMX connectors, separated by commas

Default value: jmxrmi,ssljmxrmi

imq.jmx.connector.activelist

String

Names of JMX connectors to be activated at broker startup, separated by commas

Default value: jmxrmi

imq.jmx.connector.connectorName.urlpath

String

urlPath component of JMX service URL for connector connectorName

Useful in cases where the JMX service URL path must be set explicitly (such as when a shared external RMI registry is used).

Default value: If an RMI registry is used to store the RMI stub for JMX connectors (that is, if imq.jmx.registry.start or imq.jmx.registry.use is true)

   /jndi/rmi://brokerHost:rmiPort
      /brokerHost/brokerPort/connectorName

If an RMI registry is not used (the default case, imq.jmx.registry.start and imq.jmx.registry.use both false):

   /stub/rmiStub

where rmiStub is an encoded and serialized representation of the RMI stub itself

 

imq.jmx.connector.connectorName.useSSL

Boolean

Specifies whether to use a Secure Socket Layer (SSL) for connector connectorName.

Default value: false

imq.jmx.connector.connectorName.brokerHostTrusted

Boolean

Specifies whether to trust any certificate presented by broker for connector connectorName.

Applies only when imq.jmx.connector.connectorName.useSSL is true.

If false, the Message Queue client runtime will validate all certificates presented to it. Validation will fail if the signer of the certificate is not in the client's trust store.

If true, validation of certificates is skipped. This can be useful, for instance, during software testing when a self-signed certificate is used.

Default value: false

The imq.jmx.connector.list property defines a set of named JMX connectors to be created at broker startup; imq.jmx.connector.activelist specifies which of these are to be activated. Each named connector then has its own set of properties:

imq.jmx.connector.connectorName.urlpath

imq.jmx.connector.connectorName.useSSL

imq.jmx.connector.connectorName.brokerHostTrusted

By default, two JMX connectors are created, named jmxrmi and ssljmxrmi; the first is configured not to use SSL encryption (imq.jmx.connector.jmxrmi.useSSL = false, the second to use it (imq.jmx.connector.ssljmxrmi.useSSL = true). By default, only the jmxrmi connector is activated at broker startup; see SSL Support for JMX Clients for information on how to activate the ssljmxrmi connector for secure communications.

For convenience, new options (Table 1–4) are also added to the command-line Broker utility (imqbrokerd) to control the usage, startup, and port for the RMI registry. The use and effects of these options are the same as those of the equivalent broker properties, as described in Table 1–3. The table lists each option, specifies its equivalent broker property, and describes its use.

Table 1–4 New Broker Utility Options for JMX Support

Option 

Equivalent Broker Property 

Description 

-startRmiRegistry

imq.jmx.rmiregistry.start

Specifies whether to start RMI registry at broker startup.

-useRmiRegistry

imq.jmx.rmiregistry.use

Specifies whether to use external RMI registry.

-rmiRegistryPort

imq.jmx.rmiregistry.port

The port number of RMI registry

A new subcommand (Table 1–5) is added to the command-line Command utility (imqcmd) for listing the JMX service URLs of JMX connectors created and started at broker startup. This information is needed by JMX clients that do not use the Message Queue convenience class AdminConnectionFactory to obtain their JMX connectors, and can also be used for managing or monitoring Message Queue via a generic JMX browser such as the Java Monitoring and Management Console (jconsole).

Table 1–5 New Command Utility Subcommand

Subcommand 

Description 

list jmx

List JMX service URLs of JMX connectors

SSL Support for JMX Clients

As mentioned above, a Message Queue message broker is configured by default for insecure communication using the preconfigured JMX connector jmxrmi. Applications wishing to use the Secure Socket Layer (SSL) for secure communication must activate the alternate, secure JMX connector, ssljmxrmi. This requires the following steps:

  1. Obtain and install a signed certificate in the same way as for the ssljms, ssladmin, or cluster connection service, as described in the Message Queue Administration Guide.

  2. Install the root certification authority certificate in the trust store if necessary.

  3. Add the ssljmxrmi connector to the list of JMX connectors to be activated at broker startup:

    imq.jmx.connector.activelist=jmxrmi,ssljmxrmi

  4. Start the broker with the Message Queue Broker utility (imqbrokerd), either passing it the key-store password in a password file or typing it from the command line when prompted.

  5. By default, the ssljmxrmi connector (or any other SSL-based connector) is configured to validate all broker SSL certificates presented to it. To avoid this validation (for instance, when using self-signed certificates during software testing), set the broker property imq.jmx.connector.ssljmxrmi.brokerHostTrusted to true.

On the client side, the administrator connection factory (AdminConnectionFactory) must be configured with a URL specifying ssljmxrmi as the preferred connector:

AdminConnectionFactory  acf = new AdminConnectionFactory();
acf.setProperty(AdminConnectionConfiguration.imqAddress, "mq://myhost:7676/ssljmxrmi");

If needed, use the system properties javax.net.ssl.trustStore and javax.net.ssl.trustStorePassword to point the JMX client to the trust store.

Client Runtime Logging

This section describes Message Queue 4.0 support for client runtime logging of connection and session-related events.

JDK 1.4 (and above) includes the java.util.logging library. This library implements a standard logger interface that can be used for application-specific logging.

The Message Queue client runtime uses the Java Logging API to implement its logging functions. You can use all the J2SE 1.4 logging facilities to configure logging activities. For example, an application can use the following Java logging facilities to configure how the Message Queue client runtime outputs its logging information:

For more information about the Java Logging API, please see the Java Logging Overview at http://java.sun.com/j2se/1.4.2/docs/guide/util/logging/overview.html

Logging Name Spaces, Levels, and Activities

The Message Queue provider defines a set of logging name spaces associated with logging levels and logging activities that allow Message Queue clients to log connection and session events when a logging configuration is appropriately set.

The root logging name space for the Message Queue client runtime is defined as javax.jms. All loggers in the Message Queue client runtime use this name as the parent name space.

The logging levels used for the Message Queue client runtime are the same as those defined in the java.util.logging.Level class. This class defines seven standard log levels and two additional settings that you can use to turn logging on and off.

OFF

Turns off logging.

SEVERE

Highest priority, highest value. Application-defined.

WARNING

Application-defined.

INFO

Application-defined.

CONFIG

Application-defined

FINE

Application-defined.

FINER

Application-defined.

FINEST

Lowest priority, lowest value. Application-defined.

ALL

Enables logging of all messages.

In general, exceptions and errors that occur in the Message Queue client runtime are logged by the logger with the javax.jms name space.

The following tables list the events that can be logged and the log level that must be set to log events for JMS connections and for sessions.

The following table describes log levels and events for connections.

Table 1–6 Log Levels and Events for javax.jms.connection Name Space

Log Level 

Events 

FINE

Connection created 

FINE

Connection started 

FINE

Connection closed 

FINE

Connection broken 

FINE

Connection reconnected 

FINER

Miscellaneous connection activities such as setClientID

FINEST

Messages, acknowledgments, Message Queue action and control messages (like committing a transaction)  

For sessions, the following information is recorded in the log record.

The table below describes log levels and events for sessions.

Table 1–7 Log Levels and Events for javax.jms.session Name Space

Log Level 

Event 

FINE

Session created 

FINE

Session closed 

FINE

Producer created 

FINE

Consumer created 

FINE

Destination created 

FINER

Miscellaneous session activities such as committing a session. 

FINEST

Messages produced and consumed. (Message properties and bodies are not logged in the log records.) 

By default, the output log level is inherited from the JRE in which the application is running. Check the JRE_DIRECTORY/lib/logging.properties file to determine what that level is.

You can configure logging programmatically or by using configuration files, and you can control the scope within which logging takes place. The following sections describe these possibilities.

Using the JRE Logging Configuration File

The following example shows how you set logging name spaces and levels in the JRE_DIRECTORY/lib/logging.properties file, which is used to set the log level for the Java runtime environment. All applications using this JRE will have the same logging configuration. The sample configuration below sets the logging level to INFO for the javax.jms.connection name space and specifies that output be written to java.util.logging.ConsoleHandler.

#logging.properties file.
# "handlers" specifies a comma separated list of log Handler 
# classes. These handlers will be installed during VM startup.
# Note that these classes must be on the system classpath.
# By default we only configure a ConsoleHandler, which will only
# show messages at the INFO and above levels.

	handlers= java.util.logging.ConsoleHandler

# Default global logging level.
# This specifies which kinds of events are logged across
# all loggers. For any given facility this global level
# can be overriden by a facility-specific level.
# Note that the ConsoleHandler also has a separate level
# setting to limit messages printed to the console.

    .level= INFO

# Limit the messages that are printed on the console to INFO and above.

    java.util.logging.ConsoleHandler.level = INFO
    java.util.logging.ConsoleHandler.formatter = 
                                    java.util.logging.SimpleFormatter

# The logger with javax.jms.connection name space will write
# Level.INFO messages to its output handler(s). In this configuration 
# the ouput handler is set to java.util.logging.ConsoleHandler.

    javax.jms.connection.level = INFO

Using a Logging Configuration File for a Specific Application

You can also define a logging configuration file from the java command line that you use to run an application. The application will use the configuration defined in the specified logging file. In the following example, configFile uses the same format as defined in the JRE_DIRECTORY/lib/logging.properties file.

java -Djava.util.logging.config.file=configFile MQApplication

Setting the Logging Configuration Programmatically

The following code uses the java.util.logging API to log connection events by changing the javax.jms.connection name space log level to FINE. You can include such code in your application to set logging configuration programmatically.

import java.util.logging.*;
//construct a file handler and output to the mq.log file 
//in the system's temp directory.

    Handler fh = new FileHandler("%t/mq.log");
    fh.setLevel (Level.FINE);

//Get Logger for "javax.jms.connection" domain.

    Logger logger = Logger.getLogger("javax.jms.connection");
    logger.addHandler (fh);

//javax.jms.connection logger would log activities   
//with level FINE and above.

    logger.setLevel (Level.FINE);

Connection Event Notification

Connection event notifications allow a Message Queue client to listen for closure and reconnection events and to take appropriate action based on the notification type and the connection state. For example, when a failover occurs and the client is reconnected to another broker, an application might want to clean up its transaction state and proceed with a new transaction.

If the Message Queue provider detects a serious problem with a connection, it calls the connection object's registered exception listener. It calls the listener's onException method, and passes it a JMSException argument describing the problem. The Message Queue provider also offers an event notification API that allows the client runtime to inform the application about connection state changes. The notification API is defined by the following elements:

The following sections describe the events that can trigger notification and explain how you can create an event listener.

Connection Events

The following table lists and describes the events that can be returned by the event listener.

Note that the JMS exception listener is not called when a connection event occurs. The exception listener is only called if the client runtime has exhausted its reconnection attempts. The client runtime always calls the event listener before the exception listener.

Table 1–8 Notification Events

Event Type 

Meaning 

ConnectionClosingEvent

The Message Queue client runtime generates this event when it receives a notification from the broker that a connection is about to be closed due to a shutdown requested by the administrator. 

ConnectionClosedEvent

The Message Queue client runtime generates this event when a connection is closed due to a broker error or when it is closed due to a shutdown or restart requested by the administrator. 

When an event listener receives a ConnectionClosedEvent, the application can use the getEventCode() method of the received event to get an event code that specifies the cause for closure.

ConnectionReconnectedEvent

The Message Queue client runtime has reconnected to a broker. This could be the same broker to which the client was previously connected or a different broker.  

An application can use the getBrokerAddress method of the received event to get the address of the broker to which it has been reconnected.

ConnectionReconnectFailedEvent

The Message Queue client runtime has failed to reconnect to a broker. Each time a reconnect attempt fails, the runtime generates a new event and delivers it to the event listener. 

The JMS exception listener is not called when a connection event occurs. It is only called if the client runtime has exhausted its reconnection attempts. The client runtime always calls the event listener before the exception listener. 

Creating an Event Listener

The following code example illustrates how you set a connection event listener. Whenever a connection event occurs, the event listener's onEvent method will be invoked by the client runtime.

//create an MQ connection factory.

com.sun.messaging.ConnectionFactory factory =
        new com.sun.messaging.ConnectionFactory();

//create an MQ connection.

com.sun.messaging.jms.Connection connection = 
       (com.sun.messaging.jms.Connection )factory.createConnection();

//construct an MQ event listener.  The listener implements 
//com.sun.messaging.jms.notification.EventListener interface.

com.sun.messaging.jms.notification.EventListener eListener = 
       new ApplicationEventListener();

//set event listener to the MQ connection.

connection.setEventListener ( eListener );

Event Listener Examples

In this example, an application chooses to have its event listener log the connection event to the application's logging system:

public class ApplicationEventListener implements
				com.sun.messaging.jms.notification.EventListener {

public void onEvent ( com.sun.messaging.jms.notification.Event connEvent ) {
      	log (connEvent);
}
private void log ( com.sun.messaging.jms.notification.Event connEvent ) {
	      String eventCode = connEvent.getEventCode(); 
      	String eventMessage = connEvent.getEventMessage();
    	  //write event information to the output stream.
     	}
}