Sun Java System Message Queue 4.0 Developer's Guide for JMX Clients

Chapter 1 Introduction to Message Queue JMX

The Java Management Extensions (JMX) define an architecture with which client applications can expose their resources for configuration and monitoring purposes. Sun Java System Message Queue 4.0 incorporates a JMX-compliant application programming interface for managing Message Queue–related resources such as message brokers, connections, and destinations. This interface allows Java-based Message Queue client applications to programmatically configure and monitor information that previously was accessible only from the command line or the interactive Administration Console.

The Message Queue 4.0 installation includes two Java packages related to the JMX interface:

These packages are contained in a Java archive file, imqjmx.jar, included in your Message Queue installation at the following locations, depending on your platform:

To do application development for the Message Queue JMX API, you must include this .jar file in your CLASSPATH environment variable.


Note –

Message Queue’s JMX interface requires version 1.5 of the Java Development Kit (JDK). The functionality described here is not available under earlier versions of the JDK.


Message Queue MBeans

The JMX architecture is based on the notion of a managed bean, or MBean, a Java object conforming to the management interface defined in the JMX Specification. This management interface consists of the following:

Message Queue 's JMX functionality is exposed through MBeans associated with various Message Queue resources. These MBeans are of two kinds: resource MBeans and manager MBeans. The attributes, operations, and notifications available for each type of MBean are described in detail in Chapter 2, Message Queue MBean Reference.

Resource MBeans

Resource MBeans are associated with individual Message Queue resources of the following types:

Configuration and monitoring functions are implemented by separate MBeans. Each managed resource is associated with a configuration MBean for setting the resource's configuration and a monitor MBean for gathering (typically transient) information about its runtime state. For instance, there is a destination configuration MBean for configuring a destination and a destination monitor MBean for obtaining runtime information about it. In general, each instance of a managed resource has its own pair of MBeans: thus there is a separate destination configuration MBean and destination monitor MBean for each individual destination. (In the case of the Java Virtual Machine, there is only a JVM monitor MBean with no corresponding configuration MBean.)

Configuration MBeans are used to perform such tasks as the following:

Monitor MBeans are used to obtain runtime information such as the following:

Manager MBeans

In addition to the resource MBeans associated with individual resources, there are also manager MBeans for managing some whole categories of resources. These manager MBeans also come in pairs—one for configuration and one for monitoring—for the following resource categories:

Unlike individual resource MBeans, a broker has only one pair of manager MBeans for each whole category of resources: for instance, a single destination manager configuration MBean and a single destination manager monitor MBean. For some categories (connection services, connections, destinations), the manager MBeans exist in addition to the ones for individual resources, and are used to manage the collection of resource MBeans within the category or to perform global tasks that are beyond the scope of individual resource MBeans. Thus, for instance, there is a connection manager configuration MBean and a connection manager monitor MBean in addition to the connection configuration and connection monitor MBeans associated with individual connections. Manager MBeans of this type are used to perform tasks such as the following:

In other cases (message producers, message consumers, transactions), there are no MBeans associated with individual resources and all of the resources in the category are managed through the manager MBeans themselves. The manager MBeans for these categories can be used for such tasks as the following:

Object Names

Each individual MBean is designated by an object name belonging to the JMX class ObjectName, which encapsulates a string identifying the MBean. For Message Queue MBeans, the encapsulated name string has the following syntax:

com.sun.messaging.jms.server:property=value[,property=value]*

Table 1–1 shows the possible properties.

Table 1–1 Object Name Properties

Property 

Description 

Values 

type

MBean type 

See Table 1–2.

subtype

MBean subtype 

See Table 1–3.

desttype

Destination type 

Applies only to MBeans of the following types:  

  • Destination configuration

  • Destination monitor

See Table 1–4.

name

Resource name 

Applies only to MBeans of the following types:  

  • Service configuration

  • Service monitor

  • Destination configuration

  • Destination monitor

For service configuration and service monitor MBeans, see Table 1–5.

For destination configuration and destination monitor MBeans, the destination name.  

Examples:

  • myTopic

  • temporary_destination://queue/129.145.180.99/63008/1

id

Resource identifier 

Applies only to MBeans of the following types:  

  • Connection configuration

  • Connection monitor

Example: 7853717387765338368

Table 1–2 shows the possible values for the object name's type property.

Table 1–2 Message Queue MBean Types

Value 

Description 

Broker

Broker resource MBean 

Service

Connection service resource MBean 

ServiceManager

Connection service manager MBean 

Connection

Connection resource MBean 

ConnectionManager

Connection manager MBean 

Destination

Destination resource MBean 

DestinationManager

Destination manager MBean 

ProducerManager

Message producer manager MBean 

ConsumerManager

Message consumer manager MBean 

TransactionManager

Transaction manager MBean 

Cluster

Broker cluster resource MBean 

Log

Logging resource MBean 

JVM

JVM resource MBean

Table 1–3 shows the possible values for the object name's subtype property.

Table 1–3 Message Queue MBean Subtypes

Value 

Description 

Config

Configuration MBean 

Monitor

Monitor MBean 

For destination configuration and destination monitor MBeans, the object name's desttype property specifies whether the destination is a point-to-point queue or a publish/subscribe topic. Table 1–4 shows the possible values, which are defined for convenience as static constants in the utility class DestinationType.

Table 1–4 Destination Types

Value 

Utility Constant 

Meaning 

q

DestinationType.QUEUE

Queue (point-to-point) destination 

t

DestinationType.TOPIC

Topic (publish/subscribe) destination 

For service configuration and service monitor MBeans, the object name's name property identifies the connection service with which the MBean is associated. Table 1–5 shows the possible values.

Table 1–5 Connection Service Names

Service Name 

Service Type 

Protocol Type

jms

Normal 

TCP

ssljms

Normal 

TLS (SSL-based security)

httpjms

Normal 

HTTP

httpsjms

Normal 

HTTPS (SSL-based security)

admin

Admin 

TCP

ssladmin

Admin 

TLS (SSL-based security)

The following are some example object names:

The object names for each type of Message Queue MBean are given in the relevant sections of Chapter 2, Message Queue MBean Reference. All such names are either defined as static constants or returned by static methods in the utility class MQObjectName (see Table 1–6). For instance, the constant

MQObjectName.BROKER_CONFIG_MBEAN_NAME

is defined as a string representing the object name for a broker configuration MBean, and the method call

MQObjectName.createDestinationMonitor(DestinationType.TOPIC, "Dest");

returns the destination monitor MBean object name shown above. Note that, whereas methods such as createDestinationMonitor return an actual object name (that is, an object of class ObjectName) that can be assigned directly to a variable of that type

ObjectName  destMonitorName
    = MQObjectName.createDestinationMonitor(DestinationType.TOPIC, "Dest");

constants like BROKER_CONFIG_MBEAN_NAME instead represent an ordinary string (class String) that must then be converted into the corresponding object name itself:

ObjectName  brokerConfigName = new ObjectName(MQObjectName.BROKER_CONFIG_MBEAN_NAME);
Table 1–6 Utility Constants and Methods for Object Names

MBean Type 

Utility Constant or Method 

Broker configuration 

MQObjectName.BROKER_CONFIG_MBEAN_NAME

Broker monitor 

MQObjectName.BROKER_MONITOR_MBEAN_NAME

Service configuration 

MQObjectName.createServiceConfig

Service monitor 

MQObjectName.createServiceMonitor

Service manager configuration 

MQObjectName.SERVICE_MANAGER_CONFIG_MBEAN_NAME

Service manager monitor 

MQObjectName.SERVICE_MANAGER_MONITOR_MBEAN_NAME

Connection configuration 

MQObjectName.createConnectionConfig

Connection monitor 

MQObjectName.createConnectionMonitor

Connection manager configuration 

MQObjectName.CONNECTION_MANAGER_CONFIG_MBEAN_NAME

Connection manager monitor 

MQObjectName.CONNECTION_MANAGER_MONITOR_MBEAN_NAME

Destination configuration 

MQObjectName.createDestinationConfig

Destination monitor 

MQObjectName.createDestinationMonitor

Destination manager configuration 

MQObjectName.DESTINATION_MANAGER_CONFIG_MBEAN_NAME

Destination manager monitor 

MQObjectName.DESTINATION_MANAGER_MONITOR_MBEAN_NAME

Producer manager configuration 

MQObjectName.PRODUCER_MANAGER_CONFIG_MBEAN_NAME

Producer manager monitor 

MQObjectName.PRODUCER_MANAGER_MONITOR_MBEAN_NAME

Consumer manager configuration 

MQObjectName.CONSUMER_MANAGER_CONFIG_MBEAN_NAME

Consumer manager monitor 

MQObjectName.CONSUMER_MANAGER_MONITOR_MBEAN_NAME

Transaction manager configuration 

MQObjectName.TRANSACTION_MANAGER_CONFIG_MBEAN_NAME

Transaction manager monitor 

MQObjectName.TRANSACTION_MANAGER_MONITOR_MBEAN_NAME

Cluster configuration 

MQObjectName.CLUSTER_CONFIG_MBEAN_NAME

Cluster monitor 

MQObjectName.CLUSTER_MONITOR_MBEAN_NAME

Log configuration 

MQObjectName.LOG_CONFIG_MBEAN_NAME

Log monitor 

MQObjectName.LOG_MONITOR_MBEAN_NAME

JVM monitor

MQObjectName.JVM_MONITOR_MBEAN_NAME

Utility Classes

The package com.sun.messaging.jms.management.server in the Message Queue JMX interface contains a collection of utility classes defining useful static constants and methods for use with Message Queue MBeans. Table 1–7 lists these utility classes; see the relevant sections of Chapter 2, Message Queue MBean Reference and the Message Queue JMX JavaDoc documentation for further details.

Table 1–7 Message Queue JMX Utility Classes

Class 

Description 

MQObjectName

Constants and methods for Message Queue MBean object names 

MQNotification

Superclass for all Message Queue JMX notifications

BrokerAttributes

Names of broker attributes 

BrokerOperations

Names of broker operations 

BrokerNotification

Constants and methods related to broker notifications 

BrokerState

Constants related to broker state 

ServiceAttributes

Names of connection service attributes 

ServiceOperations

Names of connection service operations 

ServiceNotification

Constants and methods related to connection service notifications 

ServiceState

Constants related to connection service state 

ConnectionAttributes

Names of connection attributes 

ConnectionOperations

Names of connection operations 

ConnectionNotification

Constants and methods related to connection notifications 

DestinationAttributes

Names of destination attributes 

DestinationOperations

Names of destination operations 

DestinationNotification

Constants and methods related to destination notifications 

DestinationType

Names of destination types 

DestinationState

Constants related to destination state 

DestinationLimitBehavior

Names of destination limit behaviors 

DestinationPauseType

Constants related to destination pause type 

ProducerAttributes

Names of message producer attributes 

ProducerOperations

Names of message producer operations 

ProducerInfo

Field names in composite data object for message producers 

ConsumerAttributes

Names of message consumer attributes 

ConsumerOperations

Names of message consumer operations 

ConsumerInfo

Field names in composite data object for message consumers 

TransactionAttributes

Names of transaction attributes 

TransactionOperations

Names of transaction operations 

TransactionNotification

Constants and methods related to transaction notifications 

TransactionInfo

Field names in composite data object for transactions 

TransactionState

Constants related to transaction state 

ClusterAttributes

Names of broker cluster attributes 

ClusterOperations

Names of broker cluster operations 

ClusterNotification

Constants and methods related to broker cluster notifications 

BrokerClusterInfo

Field names in composite data object for broker clusters 

LogAttributes

Names of logging attributes 

LogNotification

Constants and methods related to logging notifications 

LogLevel

Names of logging levels 

JVMAttributes

Names of Java Virtual Machine (JVM) attributes

MBean Server

As defined in the JMX Specification, a client application obtains access to MBeans through an MBean server. Message Queue brokers use the standard JMX-compliant MBean server provided with the Java Development Kit (JDK) 1.5.

JMX Connectors

Client applications access the MBean server by means of a JMX connector. Message Queue supports the standard RMI-based JMX connector included with JDK 1.5, which uses remote method invocation (RMI) as the infrastructure for communicating between client and server. Once you have a JMX connector, you can use it to obtain an MBean server connection with which to access the attributes, operations, and notifications of individual MBeans.

For convenience, Message Queue provides an administration connection factory (class AdminConnectionFactory), similar in spirit to the familiar Message Queue connection factory, for creating JMX connectors with a minimum of effort. It is also possible to dispense with this convenience class and obtain a JMX connector using standard JMX classes instead. The following sections illustrate these two techniques. While Message Queue client applications are free to use either method, the first is simpler and is recommended.

Obtaining a JMX Connector from an Administration Connection Factory

The Message Queue convenience class AdminConnectionFactory (defined in package com.sun.messaging) encapsulates a predefined set of configuration properties and hides the details involved in creating a JMX connector. Example 1–1 shows the most straightforward use, creating a connector at the default port 7676 on host localhost, with the user name and password both set to the default value of admin. After creating the connector, its getMBeanServerConnection method is called to obtain a server connection for interacting with Message Queue MBeans.


Example 1–1 Obtaining a JMX Connector from an Administration Connection Factory

import javax.management.remote.*;
import com.sun.messaging.AdminConnectionFactory;


//  Create administration connection factory for default host and port (localhost:7676)
    AdminConnectionFactory  acf = new AdminConnectionFactory();
    
//  Get JMX connector using default user name (admin) and password (admin)
    JMXConnector  jmxc = acf.createConnection();
    
//  Get MBean server connection
    MBeanServerConnection  mbsc = jmxc.getMBeanServerConnection();

Example 1–2 shows how to reconfigure an administration connection factory's properties to nondefault values. Instead of using the default broker address (localhost:7676), the code shown here uses the connection factory's setProperty method to reconfigure it to connect to a broker at port 9898 on host otherhost. (The names of the connection factory's configuration properties are defined as static constants in the Message Queue utility class AdminConnectionConfiguration, defined in package com.sun.messaging.) The arguments to the factory's createConnection method are then used to supply a user name and password other than the defaults.


Example 1–2 Configuring an Administration Connection Factory

import javax.management.remote.*;
import com.sun.messaging.AdminConnectionFactory;


//  Create administration connection factory
    AdminConnectionFactory  acf = new AdminConnectionFactory();
    
//  Configure for specific broker address
    acf.setProperty(AdminConnectionConfiguration.imqAddress, "otherhost:9898");
    
//  Get JMX connector, supplying user name and password
    JMXConnector  jmxc = acf.createConnection("AliBaba", "sesame");
    
//  Get MBean server connection
    MBeanServerConnection  mbsc = jmxc.getMBeanServerConnection();

Obtaining a JMX Connector Without Using an Administration Connection Factory

The generic (non–Message Queue) way of obtaining a JMX connector, as described in the JMX Specification, is by invoking the static connect method of the standard JMX class JMXConnectorFactory (see Example 1–3). Client applications may choose to use this method instead of an administration connection factory in order to avoid dependency on Message Queue–specific classes.


Example 1–3 Obtaining a JMX Connector Without Using an Administration Connection Factory

import java.util.HashMap;
import javax.management.remote.*;


//  Provide credentials required by server for user authentication
    HashMap   environment = new HashMap();
    String[]  credentials = new String[] {"AliBaba", "sesame"};
    environment.put (JMXConnector.CREDENTIALS, credentials);
    
//  Create JMXServiceURL of JMX Connector (must be known in advance)
    JMXServiceURL  url 
        = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9999/server");
    
//  Get JMX connector
    JMXConnector  jmxc = JMXConnectorFactory.connect(url, environment);
    
//  Get MBean server connection
    MBeanServerConnection  mbsc = jmxc.getMBeanServerConnection();

The JMXConnectorFactory.connect method accepts two parameters:

The service URL is a string whose syntax is described in the next section; the environment parameter is a hash map mapping attribute names to their corresponding values. In particular, the CREDENTIALS attribute specifies the authentication credentials (user name and password) to be used in establishing a connection. The hash-map key for this attribute is defined as a static constant, CREDENTIALS, in the JMXConnector interface; the corresponding value is a 2–element string array containing the user name at index 0 and the password at index 1.

JMX Service URLs

For Message Queue applications (which always use the RMI protocol for JMX connections), the JMX service URL has the following syntax:

service:jmx:rmi://[host[:port]][urlPath]

Although host and port may be included, they are ignored by the RMI protocol. If urlPath is specified, it gives the Java Naming and Directory Interface (JNDI) location of an RMI stub (typically a location within an RMI registry) in the form

/jndi/jndiName

For example, the URL

service:jmx:rmi://myhost/jndi/rmi://myhost:1099/myhost/myjmxconnector

specifies an RMI stub at the location

rmi://myhost:1099/myhost/myjmxconnector

which is an RMI registry running at location myhost/myjmxconnector on port 1099 of host myhost.

Alternatively, if urlPath is omitted from the service URL, the JMX connector server will generate a client URL containing the actual RMI stub embedded within it in encoded and serialized form. For example, the service URL

service:jmx:rmi://localhost

will generate a client URL of the form

service:jmx:rmi://localhost/stub/rmiStub

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

Using MBeans

Once you have obtained an MBean server connection, you can use it to communicate with Message Queue (and other) MBeans and to access their attributes, operations, and notifications. The following sections describe how this is done.

Accessing MBean Attributes

The MBean server connection's getAttribute method accepts the object name of an MBean along with a string representing the name of one of its attributes, and returns the value of the designated attribute. Example 1–4 shows an example, obtaining and printing the value of a destination's MaxNumProducers attribute from its configuration MBean (described in Destination Configuration).


Example 1–4 Getting an Attribute Value

import javax.management.*;
import javax.management.remote.*;
import com.sun.messaging.AdminConnectionFactory;
import com.sun.messaging.jms.management.server.*;


public class  GetAttrValue
  { 
    public static void  main (String[]  args)
      { 
        try
          { //  Create administration connection factory
                AdminConnectionFactory  acf = new AdminConnectionFactory();
            
            //  Get JMX connector, supplying user name and password
                JMXConnector  jmxc = acf.createConnection("AliBaba", "sesame");
            
            //  Get MBean server connection
                MBeanServerConnection  mbsc = jmxc.getMBeanServerConnection();
            
            //  Create object name
                ObjectName  destConfigName
                    = MQObjectName.createDestinationConfig(DestinationType.QUEUE, "MyQueue");
            
            //  Get and print attribute value
                Integer  attrValue
                    = (Integer)mbsc.getAttribute(destConfigName, DestinationAttributes.MAX_NUM_PRODUCERS);
                System.out.println( "Maximum number of producers: " + attrValue );
            
            //  Close JMX connector
                jmxc.close();
          }
        
        catch (Exception  e)
          { System.out.println( "Exception occurred: " + e.toString() );
            e.printStackTrace();
          }
      }
  }

There is also an MBeanServerConnection method named getAttributes, which accepts an MBean object name and an array of attribute name strings, and returns a result of class AttributeList. This is an array of Attribute objects, each of which provides methods (getName and getValue) for retrieving the name and value of one of the requested attributes. Example 1–5 shows a modified version of Example 1–4 that uses getAttributes to retrieve the values of a destination's MaxNumProducers and maxNumActiveConsumers attributes from its configuration MBean (see Destination Configuration).


Example 1–5 Getting Multiple Attribute Values

import javax.management.*;
import javax.management.remote.*;
import com.sun.messaging.AdminConnectionFactory;
import com.sun.messaging.jms.management.server.*;


public class  GetAttrValues
  { 
    public static void  main (String[]  args)
      { 
        try
          { //  Create administration connection factory
                AdminConnectionFactory  acf = new AdminConnectionFactory();
            
            //  Get JMX connector, supplying user name and password
                JMXConnector  jmxc = acf.createConnection("AliBaba", "sesame");
            
            //  Get MBean server connection
                MBeanServerConnection  mbsc = jmxc.getMBeanServerConnection();
            
            //  Create object name
                ObjectName  destConfigName
                    = MQObjectName.createDestinationConfig(DestinationType.QUEUE, "MyQueue");
            
            //  Create array of attribute names
                String  attrNames[] = 
                            { DestinationAttributes.MAX_NUM_PRODUCERS,
                              DestinationAttributes.MAX_NUM_ACTIVE_CONSUMERS
                            };
            
            //  Get attributes
                AttributeList  attrList = mbsc.getAttributes(destConfigName, attrNames);
            
            //  Extract and print attribute values
                
                Object  attrValue;
                
                attrValue = attrList.get(0).getValue();
                System.out.println( "Maximum number of producers: " + attrValue.toString() );
                
                attrValue = attrList.get(1).getValue();
                System.out.println( "Maximum number of active consumers: " + attrValue.toString() );
            
            //  Close JMX connector
                jmxc.close();
          }
        
        catch (Exception  e)
          { System.out.println( "Exception occurred: " + e.toString() );
            e.printStackTrace();
          }
      }
  }

To set the value of an attribute, use the MBeanServerConnection method setAttribute. This takes an MBean object name and an Attribute object specifying the name and value of the attribute to be set. Example 1–6 uses this method to set a destination's MaxNumProducers attribute to 25.


Example 1–6 Setting an Attribute Value

import javax.management.*;
import javax.management.remote.*;
import com.sun.messaging.AdminConnectionFactory;
import com.sun.messaging.jms.management.server.*;


public class  SetAttrValue
  { 
    public static void  main (String[]  args)
      { 
        try
          { //  Create administration connection factory
                AdminConnectionFactory  acf = new AdminConnectionFactory();
            
            //  Get JMX connector, supplying user name and password
                JMXConnector  jmxc = acf.createConnection("AliBaba", "sesame");
            
            //  Get MBean server connection
                MBeanServerConnection  mbsc = jmxc.getMBeanServerConnection();
            
            //  Create object name
                ObjectName  destConfigName
                    = MQObjectName.createDestinationConfig(DestinationType.QUEUE, "MyQueue");
            
            //  Create attribute object
                Attribute  attr = new Attribute(DestinationAttributes.MAX_NUM_PRODUCERS, 25);
            
            //  Set attribute value
                mbsc.setAttribute(destConfigName, attr);
            
            //  Close JMX connector
                jmxc.close();
          }
        
        catch (Exception  e)
          { System.out.println( "Exception occurred: " + e.toString() );
            e.printStackTrace();
          }
      }
  }

Just as for getting attribute values, there is an MBeanServerConnection method named setAttributes for setting the values of multiple attributes at once. You supply an MBean object name and an attribute list giving the names and values of the attributes to be set. Example 1–7 illustrates the use of this method to set a destination's MaxNumProducers and MaxNumActiveConsumers attributes to 25 and 50, respectively.


Example 1–7 Setting Multiple Attribute Values

import javax.management.*;
import javax.management.remote.*;
import com.sun.messaging.AdminConnectionFactory;
import com.sun.messaging.jms.management.server.*;


public class  SetAttrValues
  { 
    public static void  main (String[]  args)
      { 
        try
          { //  Create administration connection factory
                AdminConnectionFactory  acf = new AdminConnectionFactory();
            
            //  Get JMX connector, supplying user name and password
                JMXConnector  jmxc = acf.createConnection("AliBaba", "sesame");
            
            //  Get MBean server connection
                MBeanServerConnection  mbsc = jmxc.getMBeanServerConnection();
            
            //  Create object name
                ObjectName  destConfigName
                    = MQObjectName.createDestinationConfig(DestinationType.QUEUE, "MyQueue");
            
            //  Create and populate attribute list
                
                AttributeList  attrList = new AttributeList();
                Attribute      attr;
                
                attr = new Attribute(DestinationAttributes.MAX_NUM_PRODUCERS, 25);
                attrList.add(attr);
                
                attr = new Attribute(DestinationAttributes.MAX_NUM_ACTIVE_CONSUMERS, 50);
                attrList.add(attr);
            
            //  Set attribute values
                mbsc.setAttributes(destConfigName, attrList);
            
            //  Close JMX connector
                jmxc.close();
          }
        
        catch (Exception  e)
          { System.out.println( "Exception occurred: " + e.toString() );
            e.printStackTrace();
          }
      }
  }

Invoking MBean Operations

To invoke an MBean operation, use the MBeanServerConnection method invoke. The first two parameters to this method are an MBean object name and a string specifying the name of the operation to be invoked. (The two remaining parameters are used for supplying parameters to the invoked operation, and are discussed in the next example.) The method returns an object that is the operation's return value (if any). Example 1–8 shows the use of this method to pause the jms connection service by invoking the pause operation of its service configuration MBean (see Service Configuration).


Example 1–8 Invoking an Operation

import javax.management.*;
import javax.management.remote.*;
import com.sun.messaging.AdminConnectionFactory;
import com.sun.messaging.jms.management.server.*;


public class  InvokeOp
  { 
    public static void  main (String[]  args)
      { 
        try
          { //  Create administration connection factory
                AdminConnectionFactory  acf = new AdminConnectionFactory();
            
            //  Get JMX connector, supplying user name and password
                JMXConnector  jmxc = acf.createConnection("AliBaba", "sesame");
            
            //  Get MBean server connection
                MBeanServerConnection  mbsc = jmxc.getMBeanServerConnection();
            
            //  Create object name
                ObjectName  serviceConfigName = MQObjectName.createServiceConfig("jms");
            
            //  Invoke operation
                mbsc.invoke(serviceConfigName, ServiceOperations.PAUSE, null, null);
            
            //  Close JMX connector
                jmxc.close();
          }
        
        catch (Exception  e)
          { System.out.println( "Exception occurred: " + e.toString() );
            e.printStackTrace();
          }
      }
  }

When the operation being invoked requires parameters, you supply them in an array as the third parameter to the MBeanServerConnection.invoke method. The method's fourth parameter is a signature array giving the class or interface names of the invoked operation's parameters. Example 1–9 shows an illustration, invoking the destination manager configuration MBean's create operation to create a new queue destination named MyQueue with the same attributes that were set in Example 1–7. The create operation (see Destination Manager Configuration) takes three parameters: the type (QUEUE or TOPIC) and name of the new destination and an attribute list specifying any initial attribute values to be set. The example shows how to set up a parameter array (opParams) containing these values, along with a signature array (opSig) giving their classes, and pass them to the invoke method.


Example 1–9 Invoking an Operation with Parameters

import javax.management.*;
import javax.management.remote.*;
import com.sun.messaging.AdminConnectionFactory;
import com.sun.messaging.jms.management.server.*;


public class  InvokeOpWithParams
  { 
    public static void  main (String[]  args)
      { 
        try
          { //  Create administration connection factory
                AdminConnectionFactory  acf = new AdminConnectionFactory();
            
            //  Get JMX connector, supplying user name and password
                JMXConnector  jmxc = acf.createConnection("AliBaba", "sesame");
            
            //  Get MBean server connection
                MBeanServerConnection  mbsc = jmxc.getMBeanServerConnection();
            
            //  Create object name
                ObjectName  destMgrConfigName 
                    = new ObjectName(MQObjectName.DESTINATION_MANAGER_CONFIG_MBEAN_NAME);
            
            //  Create and populate attribute list
                
                AttributeList  attrList = new AttributeList();
                Attribute      attr;
                
                attr = new Attribute(DestinationAttributes.MAX_NUM_PRODUCERS, 25);
                attrList.add(attr);
                
                attr = new Attribute(DestinationAttributes.MAX_NUM_ACTIVE_CONSUMERS, 50);
                attrList.add(attr);
            
            //  Create operation's parameter and signature arrays
                
                Object  opParams[] = { DestinationType.QUEUE,
                                       "MyQueue",
                                       attrList
                                     };
                
                String  opSig[] = { String.class.getName(),
                                    String.class.getName(),
                                    attrList.getClass().getName()
                                  };
            
            //  Invoke operation
                mbsc.invoke(destMgrConfigName, DestinationOperations.CREATE, opParams, opSig);
            
            //  Close JMX connector
                jmxc.close();
          }
        
        catch (Exception  e)
          { System.out.println( "Exception occurred: " + e.toString() );
            e.printStackTrace();
          }
      }
  }

Example 1–10 shows a more elaborate example combining the use of MBean operations and attributes. The destination manager monitor MBean operation getDestinations (see Destination Manager Monitor) returns an array of object names of the destination monitor MBeans for all current destinations. The example then iterates through the array, printing the name, destination type (QUEUE or TOPIC), and current state (such as RUNNING or PAUSED) for each destination.


Example 1–10 Combining Operations and Attributes

import javax.management.*;
import javax.management.remote.*;
import com.sun.messaging.AdminConnectionFactory;
import com.sun.messaging.jms.management.server.*;


public class  OpsAndAttrs
  { 
    public static void  main (String[]  args)
      { 
        try
          { //  Create administration connection factory
                AdminConnectionFactory  acf = new AdminConnectionFactory();
            
            //  Get JMX connector, supplying user name and password
                JMXConnector  jmxc = acf.createConnection("AliBaba", "sesame");
            
            //  Get MBean server connection
                MBeanServerConnection  mbsc = jmxc.getMBeanServerConnection();
            
            //  Create object name for destination manager monitor MBean
                ObjectName  destMgrMonitorName
                    = new ObjectName(MQObjectName.DESTINATION_MANAGER_MONITOR_MBEAN_NAME);
            
            //  Get destination object names
                ObjectName  destNames[] = mbsc.invoke(destMgrMonitorName,
                                                      DestinationOperations.GET_DESTINATIONS,
                                                      null,
                                                      null);
            
            //  Step through array of object names, printing information for each destination
                
                System.out.println( "Listing destinations: " );
                
                ObjectName  eachDestName;
                Object      attrValue;
                
                for ( int i = 0; i < destNames.length; ++i )
                  { eachDestName = destNames[i];
                    
                    attrValue = mbsc.getAttribute(eachDestName, DestinationAttributes.NAME);
                    System.out.println( "\tName: " + attrValue );
                    
                    attrValue = mbsc.getAttribute(eachDestName, DestinationAttributes.TYPE);
                    System.out.println( "\tTypeYPE: " + attrValue );
                    
                    attrValue = mbsc.getAttribute(eachDestName, DestinationAttributes.STATE_LABEL);
                    System.out.println( "\tState: " + attrValue );
                    
                    System.out.println( "" );
                  }
            
            //  Close JMX connector
                jmxc.close();
          }
        
        catch (Exception  e)
          { System.out.println( "Exception occurred: " + e.toString() );
            e.printStackTrace();
          }
      }
  }

Some of the Message Queue MBeans' operations and attributes return a composite data object (implementing the JMX CompositeData interface). This type of object consists of a collection of data values accessed by means of associative lookup keys. The specific keys vary from one MBean to another, and are described in the relevant sections of Chapter 2, Message Queue MBean Reference. Example 1–11 shows an illustration, invoking the consumer manager MBean's GetConsumerInfo operation (see Consumer Manager Monitor to obtain an array of composite data objects describing all current message consumers. It then steps through the array, using the lookup keys listed in Table 2–63 to retrieve and print the characteristics of each consumer.


Example 1–11 Using a Composite Data Object

import javax.management.*;
import javax.management.remote.*;
import com.sun.messaging.AdminConnectionFactory;
import com.sun.messaging.jms.management.server.*;


public class  CompData
  { 
    public static void  main (String[]  args)
      { 
        try
          { //  Create administration connection factory
                AdminConnectionFactory  acf = new AdminConnectionFactory();
            
            //  Get JMX connector, supplying user name and password
                JMXConnector  jmxc = acf.createConnection("AliBaba", "sesame");
            
            //  Get MBean server connection
                MBeanServerConnection  mbsc = jmxc.getMBeanServerConnection();
            
            //  Create object name
                ObjectName  consumerMgrMonitorName
                    = new ObjectName(MQObjectName.CONSUMER_MANAGER_MONITOR_MBEAN_NAME);
            
            //  Invoke operation
                Object  result
                    = mbsc.invoke(consumerMgrMonitorName, ConsumerOperations.GET_CONSUMER_INFO, null, null);
            
            //  Typecast result to an array of composite data objects
                CompositeData  cdArray[] = (CompositeData[])result;
            
            //  Step through array, printing information for each consumer
                
                if ( cdArray == null )
                  { System.out.println( "No message consumers found" );
                  }
                else
                  { for ( int  i = 0; i < cdArray.length; ++i )
                      { CompositeData  cd = cdArray[i];
                        
                        System.out.println( "Consumer ID: "
                                                 + cd.get(ConsumerInfo.CONSUMER_ID) );
                        System.out.println( "User: "
                                                 + cd.get(ConsumerInfo.USER) );
                        System.out.println( "Host: "
                                                 + cd.get(ConsumerInfo.HOST) );
                        System.out.println( "Connection service: "
                                                 + cd.get(ConsumerInfo.SERVICE_NAME) );
                        System.out.println( "Acknowledgment mode: "
                                                 + cd.get(ConsumerInfo.ACKNOWLEDGE_MODE_LABEL) );
                        System.out.println( "Destination name: "
                                                 + cd.get(ConsumerInfo.DESTINATION_NAME) );
                        System.out.println( "Destination type: "
                                                 + cd.get(ConsumerInfo.DESTINATION_TYPE) );
                      }
                  }
          }
        
        catch (Exception  e)
          { System.out.println( "Exception occurred: " + e.toString() );
            e.printStackTrace();
          }
        
        finally
          { if ( jmxc != null )
              { try
                  { jmxc.close();
                  }
                catch (IOException ioe)
                  { System.out.println( "I/O exception occurred: " + ioe.toString() );
                    ioe.printStackTrace();
                  }
              }
          }
      }
  }

Receiving MBean Notifications

To receive notifications from an MBean, you must register a notification listener with the MBean server. This is an object implementing the JMX interface NotificationListener, which consists of the single method handleNotification. In registering the listener with the MBean server (using the MBeanServerConnection method addNotificationListener), you supply the object name of the MBean from which you wish to receive notifications, along with a notification filter specifying which types of notification you wish to receive. (You can also provide an optional handback object to be passed to your listener whenever it is invoked, and which you can use for any purpose convenient to your application.) The MBean server will then call your listener's handleNotification method whenever the designated MBean broadcasts a notification satisfying the filter you specified.

The notification listener's handleNotification method receives two parameters: a notification object (belonging to the JMX class Notification) describing the notification being raised, along with the handback object, if any, that you supplied when you registered the listener. The notification object provides methods for retrieving various pieces of information about the notification, such as its type, the MBean raising it, its time stamp, and an MBean-dependent user data object and message string further describing the notification. The notifications raised by Message Queue MBeans belong to Message Queue–specific subclasses of Notification, such as BrokerNotification, ServiceNotification, and DestinationNotification, which add further information retrieval methods specific to each particular type of notification; see the relevant sections of Chapter 2, Message Queue MBean Reference for details.

Example 1–12 shows a notification listener for responding to Message Queue service notifications, issued by a service manager monitor MBean. On receiving a notification belonging to the Message Queue class ServiceNotification, the listener simply prints an informational message containing the notification's type and the name of the connection service affected.


Example 1–12 Notification Listener

import javax.management.*;
import javax.management.remote.*;
import com.sun.messaging.jms.management.server.*;


public class  ServiceNotificationListener implements NotificationListener
  { 
    public void  handleNotification (Notification  notification,
                                     Object        handback)
      { 
        if ( notification instanceOf ServiceNotification )
          { ServiceNotification  n = (ServiceNotification)notification;
          }
        else
          { System.err.println( "Wrong type of notification for listener" );
            return;
          }
        
        System.out.println( "\nReceived service notification: " );
        System.out.println( "\tNotification type: " + n.getType() );
        System.out.println( "\tService name: " + n.getServiceName() );
        
        System.out.println( "" );
      }
  }

Example 1–13 shows how to register the notification listener from Example 1–12, using the MBeanServerConnection method addNotificationListener. The notification filter is an object of the standard JMX class NotificationFilterSupport; the calls to this object's enableType method specify that the listener should be invoked whenever a connection service is paused or resumed. The listener itself is an instance of class ServiceNotificationListener, as defined in Example 1–12.


Example 1–13 Registering a Notification Listener

import javax.management.*;
import javax.management.remote.*;
import com.sun.messaging.AdminConnectionFactory;
import com.sun.messaging.jms.management.server.*;
import java.io.IOException


public class  NotificationService
  { 
    public static void  main (String[]  args)
      { 
        try
          { //  Create administration connection factory
                AdminConnectionFactory  acf = new AdminConnectionFactory();
            
            //  Get JMX connector, supplying user name and password
                JMXConnector  jmxc = acf.createConnection("AliBaba", "sesame");
            
            //  Get MBean server connection
                MBeanServerConnection  mbsc = jmxc.getMBeanServerConnection();
            
            //  Create object name for service manager monitor MBean
                ObjectName  svcMgrMonitorName
                    = new ObjectName( MQObjectName.SERVICE_MANAGER_MONITOR_MBEAN_NAME );
            
            //  Create notification filter
                NotificationFilterSupport  myFilter = new NotificationFilterSupport();
                myFilter.enableType(ServiceNotification.SERVICE_PAUSE);
                myFilter.enableType(ServiceNotification.SERVICE_RESUME);
            
            //  Create notification listener
                ServiceNotificationListener  myListener = new ServiceNotificationListener();
                mbsc.addNotificationListener(svcMgrMonitorName, myListener, myFilter, null);
                
                ...
          }
        
        catch (Exception  e)
          { System.out.println( "Exception occurred: " + e.toString() );
            e.printStackTrace();
          }
        
        finally
          { if ( jmxc != null )
              { try
                  { jmxc.close();
                  }
                catch (IOException ioe)
                  { System.out.println( "I/O exception occurred: " + ioe.toString() );
                    ioe.printStackTrace();
                  }
              }
          }
      }
  }