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. |
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.
To build, deploy and run these
samples, you must have the following software installed on your
computer:
- OC4J 10g (10.1.3.x)
installed. This can be downloaded from http://www.oracle.com/technology/software/products/ias/index.html
- 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.
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.
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
- A System MBean
browser which allows administrators to view and operate the System level
MBeans provided by OC4J itself.
- 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.
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.
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.
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.
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:
- Set the ORACLE_HOME environment variable to the OC4J
installation directory on your system. For example:
>set ORACLE_HOME=d:\java\oc4j-1013
- Unzip the how-to-simplembeans.zip file to a directory.
>jar xf how-to-simplembeans.zip
- 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.
- 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
- 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.
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 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.
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.
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
- 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.
- 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.
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:
- 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.
- 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.
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:
- The registration of the TimerMBean
- The addition of a SimpleTimerListener object to the TimerMBean
- 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.
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.