Last Updated: 23-Feb-2004
Author: Steve Button (steve.button@oracle.com)
This set of how-to examples focuses on JMX and Management Beans (MBeans).
OC4J 10g (10.0.3) contains a JMX 1.2 server implementation, enabling MBeans to be instantiated and executed by OC4J.
OC4J 10g (10.0.3) implements the J2EE Management specification (JSR77) which defines a set of standard managed objects for a J2EE container, enabling it to be represented and managed in a standard way.
OC4J10g (10.0.3) implements the J2EE Deployment API specification (JSR88) which provides a standard API for conducting deployment operations on a J2EE container.
In this how-to, you will build and deploy a set of MBeans to an OC4J 10g (10.0.3) instance and use the OC4J JMX Console (supplied with OC4J) to view and manipulate the MBeans.
To build, deploy and run these samples, you must have the following software installed on your computer:
The OC4J 10g (10.0.3) Developer Preview available on OTN is based on J2EE
1.4. Core additions to the J2EE 1.4 landscape are set of specifications which
govern
and
define
a standard mechanism for managing a J2EE container implementation, the applications
that it has deployed, and the way those applications are deployed.
Java Management Extensions (JMX) provides an API and services to allow standard
management interfaces to be created for Java applications. Using JMX, an application
can provide its own set of Management Beans (MBeans) which will expose a set
of management operations to control the application, provide access to the
configuration
settings of the application, and even allow for statistics to be gathered and
reported by the application. By developing to the JMX standard, MBeans that
are supplied with an application can be discovered, instantiated, and accessed
by an MBeanServer.
The MBeanServer can run as a standalone component, or it can run as an embedded
service of a J2EE container. When running from within a J2EE container, the
MBeanServer effectively exposes MBeans to the other components of the J2EE
container, and to administrators to perform management operations.
The J2EE 1.4 specification also requires the implementation of the J2EE Management Specification. This effectively requires J2EE vendors to implement a set of mandatory MBeans for the various components of the J2EE server itself, providing a set of standardized management interfaces for a J2EE container.
The MBeanServer can provide access to its MBeans over a number of different protocols.via connectors and protocol adapters. Through the connectors, management applications can gain access to, and execute operations on the MBeans running in the MBeanServer.
With the introduction of JMX and the J2EE Management specification, J2EE provides a very strong management capability, with a set of standard MBeans provided by the J2EE container, and enabling applications to provide their own management functionality which can be used in a standard way.
OC4J 10g (10.0.3) comes equipped with a a JMX 1.2 compatible server implementation, enabling it to fulfill the JMX and J2EE Management requirements of J2EE 1.4. In addition to the core set of managed objects outlined in the J2EE Management specification, OC4J has been extended to provide MBeans for the other aspects of it that are not covered in the specification.
A web based administration console is provided with OC4J 10g (10.0.3). The admin console provides two basic flavours of operations:
The admin console is a web application which is deployed by OC4J when it is first started. The admin console can be accessed using the URL http://localhost:8888/adminoc4j.

The OC4J JMX Console provides a web front end which accesses the MBeanServer running in OC4J and displays the current MBeans which are registered. You can click on a MBean to discover its attributes, operations, notifications, and statistics, or you can issue a query to display a subset of the MBeans.

This How-To contains a number of MBean examples. The MBeans provided are not meant to be complex in nature and are really just simple introductions to getting started with building MBeans, configuring and deploying MBeans to OC4J, and starting to to explore some of the next level of services provided by the JMX API such as notifications.
There are 3 types of MBeans defined in the JMX specification.
Standard MBeans: these are the simplest to design and implement, their management interface is described by their method names.
DynamicMBeans: these must implement a specific interface, but they expose their management interface at runtime for greatest flexibility.
ModelMBeans: these are also dynamic MBeans that are fully configurable and self described at runtime; they provide a generic MBean class with default behavior for dynamic instrumentation of resources.
For more information, see the JMX 1.2 specification at http://jcp.org/aboutJava/communityprocess/final/jsr003/index3.html
To enable OC4J to instantiate custom MBeans, they need to be registered with the runtime. This can be accomplished using a static or programmatic approach.
With static registration, MBeans are defined using a <jmx-mbean> tag in the OC4J orion-application.xml file.
<jmx-mbean objectname=":name=Simple" class="demo.oc4j.jmx.standard.SimpleStandard">
<description>A simple example of a StandardMBean</description>
</jmx-mbean>
This can be done on a specific application basis by including the MBean classes within an EAR file, creating an OC4J orion-application.xml file and specifying the MBeans to be registered, then including this in application EAR file. When the application is deployed, the MBeans will be registered within the namespace of the application.
With OC4J, a convenient way to package the MBeans with an application is to place them in a JAR file. Place the JAR file inside of the EAR file, and then add a <library> tag to the OC4J orion-application.xml file to have the application load the library.
For the simplembeans.ear file the MBeans are packaged in a JAR file called simplembeans.jar and this is placed at the root level of the simplembeans.ear EAR file.

The OC4J orion-application.xml file in the META-INF directory specifies simplembeans.jar as a library for the application (and statically registers the MBeans as described earlier).
<orion-application>
<!-- Include the library which contains the MBean classes -->
<library path="simplembeans.jar"/><!-- Statically register the MBeans for this application -->
<jmx-mbean objectname=":name=Simple" class="demo.oc4j.jmx.standard.SimpleStandard">
<description>A simple example of a StandardMBean</description>
</jmx-mbean>
...
</orion-application>
OC4J will now be able to locate the MBeans and register them with the MBeanServer.
The source code for the MBean examples is included in this How-To distribution. The supplied Ant build script has multiple targets to perform the compilation, packaging, and deployment of the application. You can rebuild the MBeans from scratch using the supplied Ant build script. Deployment of the MBeans can be accomplished with the Ant script or via a number of other ways.
All of the MBeans are packaged in one application called simplembeans.ear. This application is deployed and the MBeans registered with the MBeanServer under the namespace of the application.
To build the MBeans, follow the steps below:
Successful execution of these steps should result in the creation of a simplembeans.ear file in the deploy directory, which contains the MBeans.
deploy/simplembeans.ear
The simplembeans.ear file is a standard J2EE EAR file containing a META-INF/application.xml file and an OC4J meta-inf/orion-application.xml file.
Once simplembeans.ear has been created, it can be deployed to an OC4J instance. There are several ways this can be accomplished.
The deploy target in the Ant script will deploy the EAR file to a running OC4J instance.
common:Buildfile: build.xml
[echo] Build Name: simplembeans
[echo] Build Home: D:\myprojects\java\jmx-examples\simplembeans
[echo] Build File: D:\myprojects\java\jmx-examples\simplembeans\build.xml
[echo] Build JVM : 1.4
init:
compile-simplembeans:
jar-simplembeans:
ear-simplembeans:
deploy:
[java] Notification ==> Application Deployer for simplembeans STARTS [
2004 -02-20T08:46:22.738CST ]
[java] Notification ==> Undeploy previous deployment
[java] Notification ==> Copy the archive to D:\java\oc4j-1003\j2ee
\home\applications\simplembeans.ear
[java] Notification ==> Unpacking simplembeans.ear
[java] Notification ==> Done unpacking simplembeans.ear
[java] Notification ==> Initialize simplembeans.ear begins...
[java] Notification ==> Initialize simplembeans.ear ends...
[java] Notification ==> Application Deployer for simplembeans COMPLETES
[ 2004-02-20T08:46:23.109CST ]
OC4J 10g (10.0.3) provides a prototype Administration console designed to facilitate testing of the JMX and J2EE Deployment API implementations. The administration console provides a facility to deploy applications.

Manual deployment of simplembeans.jar can be achieved by directly editing the OC4J XML configuration files.
There are five MBeans provided in this How-To. Each of the MBeans does something slightly different, although none of them are complex, and barely touch the surface of what JMX can do for you. They are designed to act almost as code-bites -- easily digestible if you want to have a quick look at what JMX is and what an MBean looks like.
The src code for this bean is in the src/demo/oc4j/jmx/standard directory.
This MBean is just about the simplest MBean that could be created. If this were a C language tutorial, this MBean would be saying "Hello World". It is a standard MBean and exposes it's attributes and methods via a Java interface (SimpleStandardMBean.java) with the implementation completed in the SimpleStandard class. The MBean is statically registered via the orion-application.xml.
SimpleStandardMBean maintains a counter, provides operations to increment, decrement and reset the counter value, and provides accessors to set and get the current counter value.
SimpleStandardMBean defines the management interface for the MBean. The interface name must end with the suffix "MBean".
package demo.oc4j.jmx.standard;
public interface SimpleStandardMBean
{
public int getCount();
public void setCount(int count);
public void decrement();
public void increment();
public void reset();
}
SimpleStandard implements the declared interface to provide the management attributes and operations. It looks just like a standard JavaBean which implements a specific interface.
package demo.oc4j.jmx.standard;
public class SimpleStandard
implements SimpleStandardMBean
{
private int _count = 0;
public SimpleStandard()
{
}
public int getCount()
{
return _count;
}
public void setCount(int count)
{
_count=count;
}
...
}
The orion-application.xml contains an entry to statically register the SimpleStandard MBean. The <jmx-mbean> tag contains the properties to use when registering the MBean, and the fully qualified classname of the MBean.
<jmx-mbean objectname=":name=Simple" class="demo.oc4j.jmx.standard.SimpleStandard">
<description>A simple example of a StandardMBean</description>
</jmx-mbean>
Note that it's the class itself and not the interface that is specified.
Once the application is deployed to OC4J, the OC4J JMX Console will displays the SimpleStandard MBean and allow it to be manipulated.
The SimpleStandard MBean is registered with a name of "Simple" as specified in the jmx-mbean tag and deployed as part of "simplembeans" application.
Clicking on the "simplembeans:name=Simple" link will load the SimpleStandard MBean into the JMX Console.

The JMX Console exposes the details of the MBean. It lists the important details of the MBean such as the name, class, and description. It also exposes the attributes of the MBean, Count in this case, as well as listing the operation names. You can manipulate the attributes and execute operations on the MBean directly from the JMX Console.

Obtaining the current value of an attribute can be accomplished by selecting the desired attribute and clicking the "Get Details" button. In the Attribute screen that follows, the current value can be obtained, and can be set to a specific value.

Invoking a method on the MBean is performed by selecting the desired method and clicking the "Get Details" button.

The increment method details are displayed and the method is invoked by clicking the "Invoke Method" button. This will cause the underlying implementation of the implement method defined in the MBean interface to be executed.

Looking at the value of the Count attribute again shows that the value has been incremented by one.

So there you have it, a simple counter MBean, deployed to OC4J, and manipulated by the OC4J JMX Console.
The src code for this bean is in the src/demo/oc4j/jmx/dynamic directory.
This MBean demonstrates how to do things in a dynamic fashion in the MBean world. In this example, we are using one MBean (DynamicRegistration) to dynamically register another MBean (Simple) using an administrator supplied name, and then invoke operations on it.
The example consists of one standard MBean interface, one implementation class. It uses the previous example, SimpleStandard as the MBean it dynamically works with.
DynamicRegistrationMBean defines the management interface for the MBean. It exposes a method to perform the registration of the other MBean using the supplied d name, and other methods to increment and get a count value from the specified MBean.
package demo.oc4j.jmx.dynamic;
public interface DynamicRegistrationMBean
{
public String registerNewSimpleMBean(String name);
public void executeIncrement(String name);
public void executeDecrement(String name);
public int getCount(String name);
}
DynamicRegistration implements the management interface. It provides the implementation which is responsible for the dynamic registration of the SimpleMBean, and the invocation of the corresponding methods on the registered MBean.
The registerNewSimpleMBean method registers a new SimpleStandard object as an MBean, with the OC4J MBeanServer using the supplied name. You could register multiple instances of the SimpleStandard MBean by calling this method multiple times with a different name. The new MBean will be registered under the namespace of the default application since the JMX Console itself (which is actually registering the new MBean) runs as part of the default application.
public String registerNewSimpleMBean(String name)
{
String ret = null;
String beanName = null;
beanName = getName(name);
try
{
SimpleStandard bean = new SimpleStandard();
ObjectName obj = new ObjectName(beanName);
// dynamically register the SimpleStandard
MBean
ObjectInstance newobj = _mbeanServer.registerMBean(bean,obj);
ret = "This seems to have worked, my name is " + newobj.getObjectName().getCanonicalName();
}
catch(Exception e)
{
e.printStackTrace();
}
}
The executeIncrement method invokes the increment method on the SimpleStandard MBean which has been registered using the invoke(...) operation provided by the MBeanServer -- effectively this method acts as a wrapper around the invoke method on the SimpleStandard MBean. It uses the name supplied to the method to locate the MBean to perform the operation on. If you have multiple instances of the bean registered under unique names, then you can invoke the increment methods on them individually.
The javax.management.MBeanServer.invoke method is powerful and can invoke methods of any given complexity by providing details about the method parameter signature and supplying the parameter values
public void executeIncrement(String name)
{
try
{
ObjectName obj = new ObjectName(getName(name));
_mbeanServer.invoke(obj,"increment",null,null);
}
catch(Exception e)
{
e.printStackTrace();
}
}
/**
* Executes the getCount method on the bean that has been dynamically registered,
using the
* MBeanServer.invoke(..) method.
* @return int - the count value
*/
public int getCount(String name)
{
int ret = -999;
try
{
ObjectName obj = new ObjectName(getName(name));
Integer val =(Integer)_mbeanServer.getAttribute(obj,"Count");
ret = val.intValue();
}
catch(Exception e)
{
e.printStackTrace();
}
return ret;
}
The orion-application.xml contains an entry to statically register the MBean. The <jmx-mbean> tag contains the properties to use when registering the MBean, and the fully qualified classname of the MBean.
<jmx-mbean objectname=":name=SimpleDynamicRegistration" class="demo.oc4j.jmx.dynamic.SimpleDynamicRegistration">
<description>An example of registering the simple
bean dynamically using a supplied name</description>
</jmx-mbean>
This example demonstrates the dynamic power of the MBean world, enabling MBeans to be dynamically registered, and interacted with.
Using the JMX Console, you can interact with the SimpleDynamicRegistration MBean.

You can register a new MBean (of type SimpleStandard) by invoking the registerNewSimpleMBean method and supplying a name for the new MBean.

The JMX Console will now show the new MBean that has been registered with the MBeanServer in the default application namespace.

Using the methods exposed by the SimpleDynamicRegistration MBean you can get the current value of the Count attribute and execute increment/decrement methods to alter its value.
Interestingly, since the dynamically registered MBean is still just an MBean, it can be still be interacted with directly from the JMX Console. You can also directly use the JMX Console to view the MBeans that have bee registered
The src code for this bean is in the src/demo/oc4j/jmx/notification directory.
A very useful capacity of the JMX specification is the concept of notifications. This allows an MBean to inform other interested parties when events occur within the MBean itself. Based on the same Counter example used in the other examples, this MBean sends out notification events when the operations (increment, decrement, reset) are invoked.
Adding support for notifications can be easily accomplished by subclasssing the javax.managemement.NotificationBroadcasterSupport class in your MBean implementation class. The NotificationBroadcasterSupport class implements the javax.management.NotificationBroadcaster interface, providing implementations of the add and remove notification listener methods, and a sendNotification method, so it reduces the work you need to do to.
The interesting aspects of this bean are
SimpleNotifier.java
public class SimpleNotifier
extends NotificationBroadcasterSupport
implements SimpleNotifierMBean
{
/**
* The notification set.
*/
private String notifications[] =
{
"increment", "decrement", "reset"
};
public MBeanNotificationInfo[] getNotificationInfo()
{
MBeanNotificationInfo[] info =
{
new MBeanNotificationInfo(notifications,"javax.management.Notification","Notifications
set for SimpleNotifier")
};
return info;
}
public void increment()
{
sendNotification(Notification(notifications[0],this,System.currentTimeMillis()));
//perform the increment task
}
...
}
The orion-application.xml contains an entry to statically register the MBean. The <jmx-mbean> tag contains the properties to use when registering the MBean, and the fully qualified classname of the MBean.
<jmx-mbean objectname=":name=SimpleNotifier" class="demo.oc4j.jmx.notification.SimpleNotifier">
<description>An example of the Simple MBean but
now with Notifications</description>
</jmx-mbean>
The notifications are discovered by the MBeanServer by it calling the getNotificationInfo method. The JMX Console lists the notifications of an MBean when they are present.

The JMX Console lists the notifications of an MBean. Click on the "Get Details" button in the MBean Notification section to see the notifications.

The notifications for the SimpleNotifier MBean are listed. The values are obtained by calling the getNotificatioInfo method on the MBean, which in turn, returns the list of notifications this MBean supports -- increment, decrement and reset.

To observe the notifications, a Java object needs to implement the javax.management.NotificationListener interface, and register interest in receiving notifications from the MBean.
Note: the current version of the OC4J JMX Console does not provide a facility to register and receive notifications from MBeans.
The src code for this bean is in the src/demo/oc4j/jmx/extendstandard directory.
Using StandardMBeans, it becomes a relatively straight forward mechanism to provide management interfaces for applications. Since the MBean server uses a reflection type approach, it can discover the attributes of the MBean (based on the set/get JavaBean idiom) as well as the operations, and then expose these at the JMX agent layer.
The one slight drawback to this is that there is no useful descriptions provided by the methods which can be displayed in the JMX Console. For example, the current SimpleStandard example MBean is displayed in the JMX Console as shown below. It is displayed with a generic overall description, and a generic description for each of the parameters for its operations.

Using Dynamic and Model MBeans, meta-data can be easily supplied to describe the MBean and provide more details about the attributes and operations. The same thing can be accomplished using Standard MBeans by directly subclassing the javax.management.StandardMBean class and overriding the getMBeanInfo method. This method is called by the MBeanServer to obtain information about the MBean itself. When using the simplest MBean approach with Standard MBeans, this method is not directly implemented by the MBean itself, meaning the information provided is a best guess, and usually is very generic in nature.
This MBean example is based on the same simple Counter example. It has been extended to provide its own meta-data to describe its attributes and operations.
The interesting aspects of this MBean are:
SimpleStandardExtend.java:
public class SimpleStandardExtend
extends StandardMBean
implements SimpleStandardExtendMBean
{
// Note that the constructor calls the super class and passes in a parameter
// which specifies the interface of this MBean.
public SimpleStandardExtend() throws NotCompliantMBeanException
{
super(SimpleStandardExtendMBean.class);
}
public MBeanInfo getMBeanInfo()
{
// Create meta-data for the Attributes of this bean, we have only one in this
case.
MBeanAttributeInfo[] matts =
{
new MBeanAttributeInfo("Count","int","The counter",true,true,false),
};
// Create meta-data for each of the operations of this bean
MBeanOperationInfo[] mops =
{
new MBeanOperationInfo("increment","increments the count by
1",null,"void",MBeanOperationInfo.ACTION_INFO),
new MBeanOperationInfo("decrement","decrements the count by
1",null,"void",MBeanOperationInfo.ACTION_INFO),
new MBeanOperationInfo("reset","Resets the counter to 0",null,"void",MBeanOperationInfo.ACTION_INFO)
};
// Create meta-data for the constructor, use reflection
to get the constructor details in this case
Class c = this.getClass();
Constructor[] theConstructors = c.getConstructors();
MBeanConstructorInfo[] mcons =
{
new MBeanConstructorInfo("The default constructor",theConstructors[0])
};
// Now create the actual MBeanInfo object, using our new meta-data objects
// The null parameter is for the notifications -- this MBean doesn't have any
MBeanInfo myInfo = new MBeanInfo(
this.getClass().getName(),
"A somewhat silly example of providing meta-data for a Standard MBean, but
you get the idea",
matts,
mcons,
mops,
null);
return myInfo;
}
The orion-application.xml contains an entry to statically register the MBean. The <jmx-mbean> tag contains the properties to use when registering the MBean, and the fully qualified classname of the MBean.
<jmx-mbean objectname=":name=SimpleExtends" class="demo.oc4j.jmx.extendstandard.SimpleStandardExtend">
<description>A simple example of an MBean that
extends StandardMBean to provide its own MBeanInfo</description>
</jmx-mbean>
This MBean example shows up in the JMX Console as SimpleExtends.

When the SimpleExtends MBean is shown, the description that is provided in the MBeanInfo object is displayed in the Description field.

The descriptions that were provided for the operations are displayed on the operation detail screens.

Using this technique with StandardMBeans lets an MBean tell an administrator much more about what it is doing than the simple descriptions obtained by the use of the reflection model. The only major consideration is that the getMBeanInfo method needs to be kept in close synch with the management interface of the MBean.
The src code for this bean is in the src/demo/oc4j/jmx/timer directory.
The JMX specification provides a standard Timer mechanism with the javax.management.timer.TimerBean. A TimerMBean can be registered with the MBeanServer and configured to broadcast notifications at specific dates and times. Java objects register with the TimerMBean and specify their interest in the notifications the TimerMBean broadcasts. The listener objects implement the javax.management.NotificationListener interface.
The SimpleTimer MBean example dynamically registers a TimerMBean with the name "MyTimerBean". It then registers an instance of the SimpleTimerListener object with the TimerMBean to receive notifications. The SimpleTimerMBean exposes an operation to allow new notifications to be added to the timer. A notification defines an event to occur. In this case, the notification is defined by specifying some data for the event, when the event should first fire, the period between the events going off, and how many times in total the event should occur.
This MBean example also uses the technique described in the SimpleExtended MBean to provide meta-data about the MBean. This is a nice use case of the technique since the addNotification operation requires the supply of a number of parameters. Without the additional descriptive information, the MBean operation would be very difficult to use.
The listener object for this example is the SimpleTimerListener class. It implements the NotificationListener interface, and outputs the details of the notifications it receives to the console.
The interesting aspects of this example are:
SimpleTimer.java
public class SimpleTimer
extends StandardMBean
implements SimpleTimerMBean
{
public SimpleTimer() throws NotCompliantMBeanException
{
super(SimpleTimerMBean.class);
try
{
// Create the new Timer object and start it
_timer = new Timer();
_timer.start();
// Register the timer object with the MBeanServer
if it is not already registered.
if(!_mbeanServer.isRegistered(new ObjectName(_timerName)))
{
_mbeanServer.registerMBean(_timer,new ObjectName(_timerName));
}
// Add a notification listener to the newly registered timer
_mbeanServer.addNotificationListener(
new ObjectName(_timerName),new
SimpleTimerListener(),null,null);
}
catch(Exception e)
{
e.printStackTrace();
}
}
/**
* Registers a new notification using the supplied information with the
* Timer MBean. The notification listener will receive messages based on
* the timeoffset, the period and the ntimes settings.
*
* @param type - the message type, any string will do
* @param message - the message text, any string will do
* @param timeoffset - the amount of time (sec) before the first notification
* @param period - the interval (sec) between notifications
* @param ntimes - how many notifications to send
* @return the ID of the registered Notification
*/
public Integer addNotification(String type, String message, int timeoffset, int
period, int ntimes)
{
Integer result = null;
try
{
// Add a notification to the timer object we have registered
result =
_timer.addNotification(type,
message,
null,
(new Date(System.currentTimeMillis()+(timeoffset*Timer.ONE_SECOND))),
(period*Timer.ONE_SECOND),ntimes,true);
}
catch(Exception e)
{
e.printStackTrace();
}
return result;
}
...
}
SimpleTimerListener.java
public class SimpleTimerListener implements NotificationListener
{
/**
* Method called when a notification is received.
* @param notification - the notification event
* @param src - the callback object
*/
public void handleNotification(Notification notification, Object src)
{
// Just dump out the details of the notification to stdout
System.out.println("\n----------------------------");
System.out.println("\nNew Message Received:");
System.out.println("\tDate: " + (new Date(notification.getTimeStamp())).toString());
System.out.println("\tSeq#: " + notification.getSequenceNumber());
System.out.println("\tType: " + notification.getType());
System.out.println("\tMessage: " + notification.getMessage());
System.out.println("" );
System.out.flush();
}
}
The orion-application.xml contains an entry to statically register the MBean. The <jmx-mbean> tag contains the properties to use when registering the MBean, and the fully qualified classname of the MBean.
<jmx-mbean objectname=":name=SimpleTimer" class="demo.oc4j.jmx.timer.SimpleTimer">
<description>An example of using an MBean Timer
to receive notification events</description>
</jmx-mbean>
Using the JMX Console, new notification events can be set for the dynamically registered TimerMBean. The MBean is registered with the name SimpleTimer.

The SimpleTimer MBean exposes an operation which allows an administrator to add a notification to the MyTimerMBean.

The addNotification operation accepts a number of parameters which are used to define a new notification. The notification type and message, how long before the notification should start, the time period between the notifications that are sent, and the number of notifications sent are used to define the notification.
In this case, a message reminding the administrator to get a new cup of coffee every five minutes (that's one wired administrator) is added to the MyTimerMBean.

The SimpleTimerListener which is registered with the MyTimerMBean receives the notifications when they are emitted from the MyTimerMBean and displays them on the console. The console output displays the time the notifications are delivered and the contents of the notification. The display below shows two consecutive notifications received by the SimpleTimerListener object, with a period of 5 minutes (300 seconds) elapsing between the notifications, and the notification sequence incrementing.

The actual TimerMBean which is dynamically registered with this MBean example is visible under the default namespace in the JMX Console.

The JMX Console can interact with the TimerMBean itself, displaying its attributes and operations.

Invoking the getNotificationMessage operation of MyTimerMBean and passing it the ID of the Coffee notification, the MBean will return the value of the message for the notification. Note that this value is the same as that displayed on the console via the SimpleTimerListener.

TimerMBeans are a convenient way to schedule events to occur from within the JMX environment.
This How-To example set provides a number of JMX MBeans, demonstrating various basic aspects of the JMX API and services available. JMX support is provided in OC4J 10g (10.0.3) along with a complete implementation of JSR77.