OC4J 10g (10.1.3) How-To: Create Simple JMX MBeans

First Created: 12-Jan-2005

Updates:

  $Date: 2006-08-09 15:07:19 +0930 (Wed, 09 Aug 2006) $
  $Author: sbutton $

Table of Contents

Change Tracking

Date Who What
12-Jan-2005 sbutton Initial creation and publication for OC4J 10g (10.1.3) Developer Preview 3
07-Jul-2005 sbutton Updated to use new JMX Application MBean Browser capabilities within Application Server Control. Use new ant tasks for deployment.
10-Jan-2006 sbutton Updated for production; changed to use new server defining properties in ant-oracle.xml to deploy to any type of OC4J target.
10-Aug-2006 sbutton Fixed missing images, rectified problem in ant-oracle.xml with loading Oracle Ant tasks.

Outline

This set of how-to examples focus on the use of JMX and Management Beans (MBeans) within applications that are deployed to an OC4J instance.

OC4J 10g (10.1.3) contains a JMX 1.2 server implementation, enabling MBeans to be instantiated and executed by OC4J.

OC4J 10g (10.1.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.1.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.1.3) instance and use Application Server Control (supplied with OC4J) to view and manipulate the MBeans.

This how-to example has been updated from it's earlier version to show the use of Application Server Control to access the MBeans using the Application MBean Browser.

Pre-Requisites

To build, deploy and run these samples, you must have the following software installed on your computer:

Mandatory

  1. OC4J 10g (10.1.3.x) installed. This can be downloaded from http://www.oracle.com/technology/software/products/ias/index.html
  2. Apache Ant. This can be downloaded from http://ant.apache.org/. Note that a version of Ant is contained within the OC4J distribution which has the Oracle Ant tasks already integrated within it.

OC4J, JMX and Application Server Control

The OC4J 10g (10.1.3) rellease available on OTN implements the J2EE 1.4 specification and it cerfified as J2EE 1.4 compatible.

Core additions to the J2EE 1.4 landscape are a set of specifications which define a standard mechanism for managing the resources and applications on a J2EE container implementation, and the way in which 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 through the mandated set of standard MBeans which must be provided by the J2EE container. It also allows applications to provide their own management functionality via MBeans, which can be exposed through the standard management mechanism.

OC4J 10g (10.1.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.

Application Server Control

A new web based administration console -- Application Server Control (ASC) -- is provided with OC4J 10g (10.1.3).

Application Server Control provides a complete management interface to allow you to perform management and deployment operations on a running OC4J instance.

In support of JMX, it provides the following

  1. A System MBean browser which allows administrators to view and operate the System level MBeans provided by OC4J itself.
  2. An Application MBean browser, allowing administrators to view and operate the MBeans that are registered by applications themselves.

Application Server Control is a web application which is deployed by OC4J when it is started for the very first time.

Application Server Control can be accessed using the URL: http://localhost:8888/em

You will be presented with a logon screen when you first access Application Server Control. Enter the username oc4jadmin and the password that was set for the oc4jadmin user when OC4J was executed for the first time.

Once you have authenticated you will see the Application Server Control home page of the OC4J instance being managed.

 

System MBean Browser

Application Server Control provides System MBean Browser which accesses the MBeanServer running in OC4J and displays the set of System MBeans that are available. You can click on a MBean in the tree control to to discover its attributes, operations, notifications, and statistics, or you can issue a query to find a specific MBean.

From the System MBean browser, you can view and configure a significant proportion of the manner in which OC4J operates.

 

Application Defined MBeans

MBeans that are provided by applications when they are deployed, and which provide specific management capabilities for a specific application are accessible in Application Server Control. However these types of MBeans are not displayed within the System MBean Browser. Instead, they are displayed within the context of the deployed application which registered them.

 

The MBean Examples

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 a small exploration into the next level of services provided by the JMX API such as notifications.

Types of MBeans

There are 3 primary 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

Simple Registration of MBeans with OC4J

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.

Static Registration

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, and including this in application EAR file. When the application is deployed, the MBeans will be registered within the namespace of the application.

Packaging MBeans with an EAR File

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.

Building and Deploying the Example MBeans

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.

Building the MBeans

To build the MBeans, follow the steps below:

  1. Set the ORACLE_HOME environment variable to the OC4J installation directory on your system. For example:

    >set ORACLE_HOME=d:\java\oc4j-1013
  2. Unzip the how-to-simplembeans.zip file to a directory.

    >jar xf how-to-simplembeans.zip
  3. Compile the MBeans by executing the default ant target.

    >ant

    D:\myprojects\java\how-to-simplembeans>ant
    Buildfile: build.xml

    common:
    [echo] BuildName: how-to-simplembeans
    [echo] BuildHome: D:\myprojects\java\how-to-simplembeans
    [echo] BuildFile: D:\myprojects\java\how-to-simplembeans\build.xml
    [echo] BuildJVM: 1.4

    oracle-env-check:

    java-env-check:

    init:
    [echo] -----> Initializing project properties

    setup:
    [echo] -----> Creating the required sub-directories
    [mkdir] Created dir: D:\myprojects\java\how-to-simplembeans\lib
    [mkdir] Created dir: D:\myprojects\java\how-to-simplembeans\build
    [mkdir] Created dir: D:\myprojects\java\how-to-simplembeans\log
    [mkdir] Created dir: D:\myprojects\java\how-to-simplembeans\build\how-to-simplembeans
    [mkdir] Created dir: D:\myprojects\java\how-to-simplembeans\build\how-to-simplembeans\META-INF
    [mkdir] Created dir: D:\myprojects\java\how-to-simplembeans\build\simplembeans

    compile-mbeans:
    [javac] Compiling 11 source files to D:\myprojects\java\how-to-simplembeans\build\simplembeans

    package-mbeans:
    [jar] Building jar: D:\myprojects\java\how-to-simplembeans\build\how-to-simplembeans\simplembeans.jar

    ear-descriptor:
    [copy] Copying 2 files to D:\myprojects\java\how-to-simplembeans\build\how-to-simplembeans\META-INF

    package-app:
    [ear] Building ear: D:\myprojects\java\how-to-simplembeans\build\how-to-simplembeans.ear
    [copy] Copying 1 file to D:\myprojects\java\how-to-simplembeans\lib

    all:
    [echo] -----> Creates and deploys all deployable units for the application

    BUILD SUCCESSFUL
    Total time: 6 seconds

Successful execution of these steps should result in the creation of a simplembeans.ear file in the lib directory, which contains the MBeans.

lib/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 which are used by the application.

Once simplembeans.ear has been created, it can be deployed to an OC4J instance. There are several ways this can be accomplished.

Deploy the MBeans Using Ant

The deploy target in the Ant script will deploy the EAR file to a running OC4J instance.

  1. Verify the deployment properties defined in the ant-oracle.properties file are correct for your environment.

    # The HTTP listening port for the target OC4J instance
    # - stand alone mode default is 8888
    # - managed mode default is 7777
    oracleas.http.port=8888

    # The administration listening port for the target OC4J instance
    # This port reprensents:
    # - the ORMI port if you are running a Stand Alone OC4J instance (default: 23791)
    # - the OPMN port if you are running OracleAS in a managed mode (default: 6003)
    # Note about the OPMN port:
    # if you do not know what is the OPMN port of your OracleAS instance
    # you can get if using the following command:
    # $ORACLE_HOME/opmn/bin/opmnctl status -port
    oracleas.admin.port=23791

    # The administrative login name for the target OracleAS instance
    oracleas.admin.user=oc4jadmin

    # The administrative password for the target OracleAS instance
    oracleas.admin.password=welcome1

    # The web site to which the deployed web modules are bound
    oracleas.binding.module=default-web-site

    # The deployer.uri is the URI that ill be used to deploy the application.
    # The URI varies depending of the type of topology
    # 1. Stand Alone OC4J instance
    # 2. Single Managed Instance (OPMN without clustering)
    # 3. Managed Cluster (OPMN with multiple clustered nodes)
    # Uncomment the URI depending of your targetted configuration
    #
    # 1. Stand alone OC4J
    oracleas.deployer.uri=deployer:oc4j:${oracleas.host}:${oracleas.admin.port}

    # 2. Single managed instance
    #oracleas.deployer.uri=deployer:oc4j:opmn://${oracleas.host}:${oracleas.admin.port}/${oracleas.oc4j.instance}

    # 3. Cluster
    #oracleas.deployer.uri=deployer:cluster:opmn://${oracleas.host}:${oracleas.admin.port}/${oracleas.oc4j.instance}

    # If you are deploying to a Managed instance you must specify the OC4J instance name
    oracleas.oc4j.instance=home

  2. Execute the deploy target in the Ant script.

    >ant deploy

    Buildfile: build.xml
    [taskdef] Could not load definitions from resource oracle/ant/taskdefs/deploy/
    antlib.xml. It could not be found.
    [taskdef] Could not load definitions from resource oracle/antlib.xml. It could
    not be found.

    common:
    [echo] BuildName: how-to-simplembeans
    [echo] BuildHome: D:\temp\1013prodhowto\how-to-simplembeans
    [echo] BuildFile: D:\temp\1013prodhowto\how-to-simplembeans\build.xml
    [echo] BuildJVM: 1.5

    oracle-env-check:

    java-env-check:

    init:
    [echo] -----> Initializing project properties

    setup:
    [echo] -----> Creating the required sub-directories

    compile-mbeans:

    package-mbeans:

    compile-web-classes:
    [echo] -----> Compile Web Classes

    web-descriptor:
    [echo] -----> Add OC4J descriptor

    package-web:

    ear-descriptor:

    package-app:

    deploy-ear:
    [echo] -----> Deploying the application module deployment (ear) file
    [echo] Target: deployer:oc4j:localhost:23791
    [oracle:deploy] Deploying application how-to-simplembeans.
    [oracle:deploy] Application deployer for how-to-simplembeans COMPLETES.

    deploy:
    [echo] -----> Deployed the application components required by OC4J for the
    execution of this application


    This will deploy the EAR file to the OC4J instance defined in the properties file using the deployment Ant tasks provided by your OC4J distribution.

Deploying Using Application Server Control (Optional)

Application Server Control provides a set of deployment tasks which can be used to deploy J2EE applications and modules.

1.

Open a new browser window.

Launch Application Server Control by entering the URL:

http://127.0.0.1:8888/em

Note: the host:port values should be used for your specific OC4J instance.

2. Logon using username oc4jadmin and the password that was set for the oc4jadmin user when OC4J was first started.
 
3. Click on the Administrations Tab and the click the Deploy button to start the deployment wizard.
 
4. Select the lib/how-to-simplembeans.ear file in the file selection dialog and click the Next button.
 
5. Specify how-to-simplembeans in the Application Name field and click the Next button.
 
6. Click the Deploy button to proceed with the deployment operation.
 
7. The application will now be deployed to the running OC4J instance, with progress messages displayed in the deployment window.
 
8. Click the Return button to exit the Deployment wizard.

A Closer Look at the MBeans

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.

SimpleStandardMBean -- The Simplest MBean

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 approach.

SimpleStandardMBean maintains a counter, provides operations to increment, decrement and reset the counter value, and provides accessors to set and get the current value of the counter attribute.

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 int decrement();
  public int increment();
  public int 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 in the registration code.

Using the static registration approach, initial values for Attributes of the MBean can be specified from within the configuration file. This is done using an <attribute> and <value> tag set within the <jmx-mbean> definition.

<jmx-mbean objectname=":name=Simple" class="demo.oc4j.jmx.standard.SimpleStandard">
  <description>A simple example of a StandardMBean</description>
  <attribute name="Count">
    <value>3336</value>
  </attribute>
</jmx-mbean>

Once the application is deployed to OC4J, Application Server Control will displays the SimpleStandard MBean and allow it to be manipulated. It will also set any initial values of attributes as specified.

The SimpleStandard MBean is registered with a name of "Simple" as specified in the jmx-mbean tag and deployed as part of "simplembeans" application.

On the Applications tab, click on the link in the Application Defined MBeans column for the SimpleMBeans application.

 

This will display all of the MBeans that have been registered by the SimpleMBeans application in a tree control.

Click on the MBean named Simple.

Application Server Control 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 Application Server Control.

 

The current value of all the attributes (Count in this case) are displayed. For attributes which have read and write operations, you can set the value of the attribute by filling in the Value form field and pressing the apply button.

 

Viewing the list of, and invoking an operation on the MBean is performed by selecting Operations tab and clicking on the desired operation.

 

In this case, the increment method details are displayed and the method is invoked by clicking the "Invoke Operation" button. This will cause the underlying implementation of the "increment" method defined in the MBean interface to be executed.

 

Click the Return button to return to the operations tab.

Now looking at the value of the Count attribute shows that the value has been incremented by one from it's previous value.

 

So there you have it, a simple counter MBean, deployed to OC4J, and exposed by Application Server Control for admins to interact with and use.

DynamicRegistration -- Registering MBeans Dynamically

The src code for this bean is in the src/demo/oc4j/jmx/dynamicregistration 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 registers under the user supplied name.

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 Application Server Control 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();
  }
}

The getCount method uses the MBeanServer.getAttribute method to obtain the value of the Count attribute on the MBean of the supplied name. If you have multiple instances of the SimpleStandard MBean registered, you can use this method to obtain the value of Count by supplying the unique name of the bean.

/**
* 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 Application Server Control, you can interact with the SimpleDynamicRegistration MBean.

 

You can register a new MBean (which is ultimately of the type SimpleStandard) by invoking the registerNewSimpleMBean method, supplying a name for the new MBean, and clicking the Invoke Operation button.

The return value from the operation shows the name used to register the new MBean object.

 

The Application MBean Browser will now show the new MBean that has been registered using the user supplied name.

 

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. You must pass in the name of the MBean you dynamically created so that the SimpleDynamicMBean can locate the MBean you registered.

 

Interestingly, since the dynamically registered MBean is still just an MBean, it can be still be interacted with directly using the Application MBean Browser.

 

SimpleNotification -- Emitting Notifications from an MBean

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

  1. How the MBean informs the MBeanServer of the notification it wants to broadcast. This is accomplished by implementing the getNotificationInfo method. This returns an array indicating, for each notification this MBean may send, the name of the Java class of the notification and the notification type.
  2. Sending the notifications using the sendNotification method.

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",
                                "Notification set for SimpleNotifier")
    };
    return info;
  }

  public void increment()
  {
    //perform the increment task
    sendNotification(Notification(notifications[0],this,System.currentTimeMillis(),"Count=" + getCount()));

  }

  ...
}

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. Application Server Control lists the notifications of an MBean when they are present on the Notifications tab.

Click on the SimpleNotifier MBean link to access it.

 

Select the Notifications tab to see the list of notifications.

 

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

Application Server Control can receive notifications from MBeans. To subscribe to the notifications, select the Subscribed checkbox next to the notification you are interested in.

In our SimpleNotification example, a notification is sent when the operations (increment, decrement and reset) are performed. Invoke these operations several times using Application Server Control.

When Notifications that are received by Application Server Control, an indicator is displayed (showing the number of notifications) on the Home page.

 

Clicking on the link will display all of the the notifications that have been received. In the example below, you can see that the increment operation was called three times, following by a decrement operation, followed by a reset.

 

Clicking on a specific notification will drill down into the specific details of that notification.

 

SimpleExtended -- Providing Meta-Data from StandardMBeans

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 Application Server Control. For example, the current SimpleStandard example MBean is displayed in Application Server Control 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 to 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:

  1. It directly subclasses the javax.management.StandardMBean class. This requires the MBean to provide its own constructor and call the constructor of its parent object and pass it the MBean interface.
  2. The overriding getMBeanInfo method. This method implementation constructs a new MBeanInfo object and populates it with the information about this MBean (attributes, operations) allowing meaningful descriptions to be provided.

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 Application Server Control as SimpleExtends.

Now when the SimpleExtends MBean is displayed in the Application MBean Browser, the description that is provided in the MBeanInfo object is now displayed in the Description field of the MBean, and the operations have useful descriptions as well.

 

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.

SimpleTimer -- Using the TimerMBean

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:

  1. The registration of the TimerMBean
  2. The addition of a SimpleTimerListener object to the TimerMBean
  3. The addition of a new notification event to the TimerMBean.

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 Application Server Control, 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 Application Server Control.

 

Since it's just an MBean, Application Server Control 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.

Summary

This How-To example walks though provides a number of JMX MBeans, demonstrating various basic aspects of the JMX API and services available, and demonstrates how Application Server Control allows administrators to operate both System and Application level MBeans.

 

Left Curve
Popular Downloads
Right Curve
Untitled Document