Sun Microsystems
Products & Services
 
Support & Training
 
 

Previous Previous     Contents     Index     Next Next

8.2.3 Adding a Listener Through the MBean Server

Now that we have identified the objects involved, we need to add the listener to the notification broadcaster. Our example does this in the main method of the agent application.

Example 8-2 Registering for MBean Server Delegate Notifications

AgentListener agentListener = null;
[...]

echo("\nRegistering the MBean server delegate listener...");
try {
    agentListener = new AgentListener();
    myAgent.server.addNotificationListener(
        new ObjectName(ServiceName.DELEGATE),
        agentListener, null, null);
} catch(Exception e) {
    e.printStackTrace();
    System.exit(1);
}
echo("done");

In Example 8-2, the agent application adds the AgentListener instance to the delegate MBean, which is known to be a broadcaster. The object name of the MBean server delegate is given by the DELEGATE constant in the ServiceName class. The listener is added through the addNotificationListener method of the MBean server. This method preserves the management architecture by adding listeners to MBeans while referring only to the MBean object names.

If an MBean implements the listener interface and needs to receive certain notifications, it can add itself to a broadcaster. For example, an MBean could use its preregistration method in order to add itself as a notification listener or it could expose a method that takes the object name of the notification broadcaster MBean. In both cases, its notification handler method must be designed to process all expected notification types.

The last two parameters of the addNotificationListener methods of both the MBeanServer and the NotificationBroadcaster interfaces define a filter and a handback object, respectively. Filter objects are defined by the NotificationFilter interface and provide a callback method that the broadcaster calls before calling the notification handler. If the filter is defined by the entity that adds the listener, it prevents the handler from receiving unwanted notifications.

Handback objects are added to a broadcaster along with a listener and are returned to the designated handler with every notification. The handback object is completely untouched by the broadcaster and can be used to transmit context information from the entity that adds the listener to the handler method. The functionality of filters and handback objects is beyond the scope of this tutorial; refer to the JMX specification for their full description.

8.3 Attribute Change Notifications

In this second part of the notification example, we demonstrate attribute change notifications that can be sent by MBeans. An MBean designer can choose to send notifications whenever the value of an attribute changes or is changed. The designer can implement this mechanism in any manner, according to the level of consistency required by the management solution.

The JMX specification only provides a subclass of notifications to use to represent the attribute change events: the AttributeChangeNotification class.

8.3.1 NotificationBroadcasterSupport Class

The broadcaster in our example is a very simple MBean. The reset method triggers a notification whenever it is called. This policy is specific to our example. You might want to design an MBean that sends an attribute change every time the setter is called, regardless of whether or not the value is modified. Your management needs might vary.

Example 8-3 shows the code for our SimpleStandard MBean class (the code for its MBean interface has been omitted).

Example 8-3 Broadcaster for Attribute Change Notifications

import javax.management.NotificationBroadcasterSupport;
import javax.management.MBeanNotificationInfo;
import javax.management.AttributeChangeNotification;

public class SimpleStandard
    extends NotificationBroadcasterSupport
    implements SimpleStandardMBean {

    public String getState() {
        return state;
    }

    public void setState(String s) {
        state = s;
        nbChanges++;
    }

    [...]
   
    public int getNbChanges() {
        return nbChanges;
    }

    public void reset() {
	         AttributeChangeNotification acn =
	             new AttributeChangeNotification(this,
					                                0,
					                                0,
					                                "NbChanges reset",
					                                "NbChanges",
					                                "Integer",
					                                new Integer(nbChanges),
					                                new Integer(0));
	         state = "initial state";
          nbChanges = 0;
	         nbResets++;
	         sendNotification(acn);
    }    

   public int getNbResets() {
       	return nbResets;
   }

   public MBeanNotificationInfo[] getNotificationInfo() {
        return new MBeanNotificationInfo[] {
	          new MBeanNotificationInfo(
	          new String[] { AttributeChangeNotification.ATTRIBUTE_CHANGE },
	          AttributeChangeNotification.class.getName(),
	          "This notification is emitted when the reset() method is 
            called.")
	   };
   
    private String      state = "initial state";
    private int         nbChanges = 0;
    private int         nbResets = 0;
}

This MBean sends its notifications and it implements the NotificationBroadcaster interface by extension of the NotificationBroadcasterSupport class, in order to provide all the mechanisms for adding and removing listeners and sending notifications. It manages an internal list of listeners and their handback objects and updates this list whenever listeners are added or removed. In addition, the NotificationBroadcasterSupport class provides the sendNotification method to send a notification to all listeners currently on its list.

By extending this object, our MBean inherits all of this behavior. Subclassing NotificationBroadcasterSupport is a quick and convenient way to implement notification broadcasters. We do not even have to call a superclass constructor because it has a default constructor. We only need to override the getNotificationInfo method to provide details about all of the notifications that might be sent.

8.3.2 Attribute Change Listener

Like our listener for MBean server notifications, our listener for attribute change notifications is a trivial class consisting of just the handler method.

Example 8-4 Listener for Attribute Change Notifications

import javax.management.Notification;
import javax.management.NotificationListener;
import javax.management.AttributeChangeNotification;

public class SimpleStandardListener implements NotificationListener {
    [...]

    // Implementation of the NotificationListener interface
    //
    public void handleNotification(Notification notification,
                                   Object handback) {

        // Process the different types of notifications fired by the
        // simple standard MBean.
        String type = notification.getType();

        System.out.println(
            "\n\t>> SimpleStandardListener received notification:" +
            "\n\t>> ---------------------------------------------");
        try {
            if (type.equals(AttributeChangeNotification.ATTRIBUTE_CHANGE)) {

  System.out.println("\t>> Attribute \"" +
      ((AttributeChangeNotification)notification).getAttributeName()
      + "\" has changed");
  System.out.println("\t>> Old value = " +
      ((AttributeChangeNotification)notification).getOldValue());
  System.out.println("\t>> New value = " +
      ((AttributeChangeNotification)notification).getNewValue());

            }                
            else {
                System.out.println("\t>> Unknown event type (?)\n");
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }
}

Previous Previous     Contents     Index     Next Next