For the previous four parts of this series, and the final part, please use the links at foot of the article
This article is the fifth in a series of articles on BEA WebLogic Server administration and management for developers (see WLDJ, Vol 2, issues 1012; Vol. 3, issue 2).
We have focused on WebLogic Server administration concepts and terminology, the graphical tools for packaging an application and setting up and configuring a WebLogic Server domain; the application deployment, runtime management, and monitoring facilities available that did not require knowledge of JMX; basic concepts and terminology of JMX and the BEA WebLogic Server 8.1 JMX infrastructure; as well as how to use JMX-specific tools that come with WebLogic Server 8.1. In our last article, we showed you the basics of how to write custom Java applications that use JMX to configure, administer, and manage WebLogic Server 8.1based applications.
This month, we'll continue our discussion of JMX programming by showing you how to use the notification facilities to create notification listeners, monitors, and timers.
JMX Notification
In addition to the ability to manipulate MBean attributes and operations, JMX also provides notifications when changes to MBean state are made. A JMX MBeanServer allows a management program to register its interest in these notifications on individual MBeans or on the MBeanServer itself. To register interest in JMX notifications, a program simply needs to create an object that implements the NotificationListener interface and register this object with the MBean or the MBeanServer. The NotificationListener interface has only one method, handleNotification(), which is the method that the MBean invokes to notify the listener:
public interface NotificationListener
extends java.util.EventListener
{
void handleNotification(Notification n, Object handback);
}
The Notification class contains information about the circumstances surrounding the event. The optional handback argument simply hands back whatever object was passed in when registering the listener. This provides a mechanism by which the listener can associate information about the MBean that's producing the notification that gets passed back to the listener without modification during the notification callback.
JMX 1.0 defines five types of notification objects that contain information specific to the type of notification:
- MBeanServerNotification: Used by the MBeanServer to notify listeners of MBean registration and deregistration
- AttributeChangeNotification: Used by MBeans to notify listeners when an attribute value changes
- MonitorNotification: Emitted by the monitoring services when a specific set of conditions is met
- RelationNotification: Emitted by the relationship service when a relation is added, updated, or removed
- TimerNotification: Emitted by the timer service when a timer goes off
In addition, BEA WebLogic Server 8.1 also defines the following notification types:
- WebLogicLogNotification: Emitted every time an entry is written to the WebLogic Server log file
- AttributeAddNotification: Emitted every time an element is added to an MBean attribute that is an array
- AttributeRemovedNotification: Emitted every time an element is removed from an MBean attribute that is an array
Listing 1 is a very simple example of a listener that does nothing more than print out the details of an AttributeChangeNotification.
There are two important points that we need to make here. First, you will notice that we have made the class serializable. The notification listener mechanism, like the other JMX interfaces, does not account for remote access. To be able to use our stand-alone client to register the listener, you need to make the listener serializable because the call to addNotificationListener() will need to pass a copy of the listener to the server. This means that the listener we just created will actually be instantiated on the server and only the server-side copy of the listener will actually receive the notifications. In fact, you'll need to make sure that the listener class is in the server's CLASSPATH for this to work. Fortunately, BEA WebLogic Server provides an extension to allow you to easily create and register a listener that runs in a remote process.
To enable remote listener notification, all you need to do is change the above class to implement the weblogic.management.RemoteNotificationListener interface instead of the javax.management.NotificationListener and java.io.Serializable interfaces. This eliminates the need to have the listener class in the server's CLASSPATH and allows the notifications to be sent back to your client-side listener.
Second, you have to filter the types of notifications you are interested in by checking the actual class of the notification object passed into the listener. While this is not a big deal in our little example, you can imagine that it gets more unwieldy as you increase the number of notification types that the listener needs to manage. Fortunately, JMX defines a filtering mechanism that allows the registering program to describe the types of events the listener wants to receive. All notification filters must implement the javax.management.NotificationFilter interface shown here:
public interface NotificationFilter extends java.io.Serializable
{
public boolean isNotificationEnabled(Notification notification);
}
The isNotificationEnabled() method returns true if the notification should be delivered to the filter and false otherwise. Notice that the NotificationFilter interface extends java.io.Serializable. The filter, much like the NotificationListener described earlier, will be copied and instantiated on the server. In this case, that is precisely what we want since we want the server to pass only the events of interest back to the client. Now we can move the filtering logic out of the listener itself and into the filter (see Listing 2).
Of course you can do much more sophisticated things with filters but a full discussion is beyond the scope of this article. Please refer to the JMX 1.0 specification (http://jcp.org/aboutJava/communityprocess/final/jsr003/) and the BEA WebLogic Server documentation (http://edocs.bea.com/wls/docs81/jmx/notifications.html) for more information.
To register your notification listener with an MBean, you simply invoke one of the addNotificationListener() methods on the MBeanServer or, if you are using WebLogic Server's strongly typed MBean interface, the addNotificationListener() method defined by the javax.management.NotificationBroadcaster interface that every WebLogic Server MBean implements. The following code snippet from the downloadable example (available online at www.sys-con.com/weblogic/sourcec.cfm) demonstrates using the MBeanServer interface:
String serverName = "mydomain:Name=myserver,Type=Server";
ObjectName serverMBeanName = new ObjectName(serverName);
MyAttributeChangeListener me =
new MyAttributeChangeListener(serverName);
MyAttributeChangeFilter filter = new MyAttributeChangeFilter();
mbeanServer.addNotificationListener(serverMBeanName, me, filter, null);
With JMX Notification, the registered listeners receive notification any time an event for which they have registered their interest occurs. If the management application really just wants to monitor the value of an MBean attribute, JMX provides another facility to accomplish this known as JMX Monitoring.
JMX Monitoring
The JMX specification requires that a JMX MBean server provide a monitoring service. JMX monitoring is surfaced through a set of MBeans known as Monitor MBeans. A management application configures these Monitor MBeans to periodically observe other MBeans and emit a JMX notification if a specific MBean attribute exceeds the configured threshold. The value of the attribute being observed, known as the derived gauge, can either be the exact value of the attribute or the difference between two consecutive observed values (if the attribute is numeric). The frequency with which the monitor samples the value of the observed attribute is called the granularity period.
Monitor MBeans come in three flavors:
- CounterMonitor: Observes integer-type attributes that behave like a counter in that the values are always greater than or equal to zero and the values are only incremented (though they can rollover)
- GaugeMonitor: Observes numeric attributes that behave like a gauge in that the values can arbitrarily fluctuate
- StringMonitor: Observes string attributes
Whenever the value of the derived gauge exceeds the configured threshold, the Monitor MBean generates a JMX notification. These notifications are sent using an instance of the MonitorNotification class, which is a subclass of the Notification class discussed earlier. This class contains information such as the notification type, the observed MBean name, the observed attribute name, the derived gauge, and the threshold value that triggered the notification. The notification types for monitors specific to the type of monitor being used are:
- jmx.monitor.counter.threshold: Generated when a CounterMonitor's derived gauge meets or exceeds the configured threshold value
- jmx.monitor.gauge.high: Generated when a GaugeMonitor's derived gauge meets or exceeds the configured high threshold
- jmx.monitor.gauge.low: Generated when a GaugeMonitor's derived gauge decreases to or below the configured low threshold
- jmx.monitor.string.matches: Generated when a StringMonitor's derived gauge first matches the configured string to compare
- jmx.monitor.string.differs: Generated when a StringMonitor's derived gauge first differs from the configured string to compare
Notifications are also generated when certain error conditions are encountered. The common set of error types are:
- jmx.monitor.error.mbean: Generated when one of the observed MBeans is not registered with the MBean server
- jmx.monitor.error.attribute: Generated when the observed attribute does not exist in one of the observed MBeans
- jmx.monitor.error.type: Generated when the observed attribute value is null or not the appropriate type for the type of monitor being used
- jmx.monitor.error.runtime: Generated when other errors are encountered while trying to get the value of the observed attribute
- jmx.monitor.error.threshold: Generated by counter or gauge monitors when the configured threshold parameters are not of the same type as the observed attribute
To use a monitor, you need to create an instance of the appropriate Monitor MBean and register it with the MBean server, configure it, add one or more listeners, and start the monitor. Creating the Monitor MBean involves creating a name for the new MBean and invoking one of the createMBean() methods on the MBeanServer:
String monitorName = "mydomain:Name=MyMonitor";
ObjectName monitorMBeanName = new ObjectName(monitorName);
ObjectInstance oiMonitor =
mbeanServer.createMBean("javax.management.monitor.GaugeMonitor", monitorMBeanName);
Using the MBeanServer.createMBean() method also registers the MBean with the MBean server. Next, we need to configure the Monitor MBean using the appropriate attributes or operations. For our JMXMonitor example, we use a GaugeMonitor and configure its attributes using the MBeanServer.setAttributes() method (see Listing 3).
Next, we invoke the setThresholds() operation:
Object[] params = new Object[2];
params[0] = new Integer(10);
params[1] = new Integer(1);
String[] signature = new String[2];
signature[0] = "java.lang.Number";
signature[1] = "java.lang.Number";
Object retval = mbeanServer.invoke(monitorMBeanName, "setThresholds", params, signature);
Then we add the listener to the monitor:
MyMonitorListener me = new MyMonitorListener();
mbeanServer.addNotificationListener(monitorMBeanName,
me, null, null);
Finally, we start the monitor:
params = new Object[0];
signature = new String[0];
retval = mbeanServer.invoke(monitorMBeanName, "start", params, signature);
Now, whenever the PendingRequestCurrentCount attribute of the weblogic.kernel.Default execute queue first exceeds 10 or first falls below 1, a notification message will be sent to the listener. Once an application is through with a monitor, it should stop the monitor and unregister it from the MBean server:
retval = mbeanServer.invoke(monitorMBeanName, "stop",
params, signature);
mbeanServer.unregisterMBean(monitorMBeanName);
If you fail to do this, the next time the application starts up it will fail unless it uses a different name for the Monitor MBean or the server has been restarted. For more information about JMX monitors, see the JMX 1.0 specification and Javadocs. JMX provides one final notification mechanism, known as the JMX Timer service, that provides the ability to be notified at a specific date and time or even at periodic intervals.
JMX Timers
The JMX timer service generates notifications in two different ways:
- Single occurrence notifications
- Repeated notifications that occur at regular intervals over a specified period of time and/or number of occurrences
Like the monitor MBean, the Timer MBean is created on the MBeanServer and configured to generate these timed notifications. Notifications generated by the Timer MBean are sent using an instance of the TimerNotification class. To create a notification, use one of the Timer MBean's addNotification() methods, which require some or all of the following arguments:
- type: String used to represent the type of notification
- message: String used to send detailed information about the notification
- userData: Optional handback object
- date: Date class used to specify when the notification should occur
- period: Interval in milliseconds between notifications (0 or null for nonrepeating notifications)
- nbOccurences: Total number of times that the notification will occur (0 or null means that it repeats indefinitely if the period is not 0 or null)
The code to create, configure, add a listener to, and start the Timer MBean looks very much like the code we used earlier when working with the JMX monitor. In the same way, your application should stop and unregister your Timer MBean when it is finished with it so that there will be no naming collisions caused by trying to create an MBean twice with the same name. Rather than list the code here, please see the downloadable examples.
Summary
In this article, we showed you how to use JMX notifications, monitors, and timers. JMX notification provides the ability for applications to register their interest in certain events and receive callbacks when those events occur. Using JMX notification with a NotificationListener provides a simple mechanism to detect predefined events generated by MBeans. Monitors provide a more sophisticated way of observing the value of an MBean attribute and receiving notification when the value of the attribute exceeds the configured threshold. JMX Timers provide a mechanism to generate a notification at a future date and time or to generate notifications at regular intervals. These JMX services provide a management application with the ability to monitor the behavior of a managed application and respond to changes without the need for human intervention.
The next and final article in this series will dive into the details of creating custom MBeans and extending the Admin Console to display them.