Contents | Previous | Next | Java Management Extensions (JMX) Technology Tutorial |
This chapter introduces the fundamental notion of the Java Management Extensions (JMX) API, namely managed beans, or MBeans.
An MBean is a managed Java object, similar to a JavaBeanTM, that follows the design patterns set forth in the instrumentation level of the JMX specification. An MBean can represent a device, an application, or any resource that needs to be managed. MBeans expose a management interface: a set of readable and/or writable attributes and a set of invokable operations, along with a self-description. The management interface does not change throughout the life of an MBean instance. MBeans can also emit notifications when certain defined events occur.
The JMX specification defines four types of MBean: standard MBeans, dynamic MBeans, open MBeans and model MBeans. The examples in this chapter demonstrate the simplest type of MBean, namely standard MBeans.
A standard MBean is defined by writing a Java
interface called SomethingMBean
and a
Java class called Something
that
implements that interface. Every method in the interface defines
either an attribute or an operation in the MBean. By default every
method defines an operation. Attributes and operations are simply
methods which follow certain design patterns. A standard MBean is
composed of the MBean interface which lists the methods for all
exposed attributes and operations, and the class which implements
this interface and provides the functionality of the instrumented
resource.
The following sections dissect an example standard
MBean, and a simple JMX agent that manages the MBean. The code
samples are taken from the directory work_dir/jmx_examples/Essential/com/example/mbeans.
An example of a very basic MBean interface, named
HelloMBean
, is shown in CODE EXAMPLE 2-1.
package com.example.mbeans; public interface HelloMBean { public void sayHello(); public int add(int x, int y); public String getName(); public int getCacheSize(); public void setCacheSize(int size); }
As stated previously, by convention an MBean
interface takes the name of the Java class that implements it, with
the suffix MBean added. So, in this case, the interface is
called HelloMBean
. The Hello
class that implements this interface is
described in Section "MBean
Implementation".
According to the JMX specification, an MBean
interface consists of named and typed attributes that are readable
and possibly writable, and named and typed operations that can be
invoked by the applications that are managed by the MBean. The
HelloMBean
interface shown in CODE EXAMPLE 2-1, declares
two operations: the Java methods add()
and sayHello()
.
Of the two attributes that are declared by
HelloMbean
, Name
is a read-only string, and CacheSize
is an integer that can be both read and
written. Getter and setter methods are declared, to allow the managed
application to access and possibly change the attribute values. As
defined by the JMX specification, a getter is any public method
whose name begins with get and which does not return void. A getter
enables a manager to read the value of the attribute, whose type is
that of the returned object. A setter is any public method whose
name begins with set and which takes a single parameter. A setter
enables a manager to write a new value in the attribute, whose type
is the same as that of the parameter.
The implementation of these operations and attributes is shown in the following section.
The Hello
class shown
in CODE EXAMPLE 2-1
implements HelloMBean
.
package com.example.mbeans; public class Hello implements HelloMBean { public void sayHello() { System.out.println("hello, world"); } public int add(int x, int y) { return x + y; } public String getName() { return this.name; } public int getCacheSize() { return this.cacheSize; } public synchronized void setCacheSize(int size) { this.cacheSize = size; System.out.println("Cache size now " + this.cacheSize); } private final String name = "Reginald"; private int cacheSize = DEFAULT_CACHE_SIZE; private static final int DEFAULT_CACHE_SIZE = 200; }
The straightforward Java class Hello
provides the definitions of the operations and
attributes declared by HelloMBean
. As
you can see, the sayHello()
and
add()
operations are extremely simple,
but real-life operations can be as simple or as sophisticated as
you like.
Methods to get the Name
attribute and to get and set the cacheSize
attribute are also defined. In this
example, the Name
attribute value never
changes, but in a real scenario it might change as the managed
resource runs. For example, the attribute might represent
statistics such as uptime or memory usage. Here, it is merely the
name “Reginald”.
Calling the setCacheSize
method allows you to alter the
cacheSize
attribute from its declared
default value of 200. In reality, changing the cacheSize
attribute could require other operations
to be performed, such as discarding entries or allocating new ones.
This example merely prints a message to confirm that the cache size
has changed, but more sophisticated operations could be defined in
the place of the simple call to println()
.
With the simple Hello
MBean and its interface thus defined, they can now be used to
manage the resource they represent, as shown in the following
section.
As presented in the Java Management Extensions (JMX) Technology Overview, once a resource has been instrumented by MBeans, the management of that resource is performed by a JMX agent.
The core component of a JMX agent is the
MBean server, a managed object server in
which MBeans are registered (see the API documentation for the
MBeanServer
interface for details of the
MBean server implementation). A JMX agent also includes a set of
services to manage MBeans.
CODE EXAMPLE 2-1 presents
a basic JMX agent, named Main
.
package com.example.mbeans; import java.lang.management.*; import javax.management.*; public class Main { public static void main(String[] args) throws Exception { MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); ObjectName name = new ObjectName("com.example.mbeans:type=Hello"); Hello mbean = new Hello(); mbs.registerMBean(mbean, name); System.out.println("Waiting forever..."); Thread.sleep(Long.MAX_VALUE); } }
The JMX agent Main
begins by obtaining any MBean server that is running on the
platform, by calling the getPlatformMBeanServer()
method of the java.lang.management.ManagementFactory
class. If
there is no MBean server already running on the platform, then
getPlatformMBeanServer()
creates one
automatically by calling the JMX method MBeanServerFactory.createMBeanServer()
. The
MBeanServer
instance obtained by
Main
is named mbs
.
Next, Main
defines an
object name for the MBean instance it will create. Every JMX MBean
must have an object name. The object name is an instance of the JMX
class ObjectName
, and must conform to
the syntax defined by the JMX specification, namely it must
comprise a domain, and a list of
key-properties (see the API
documentation for the ObjectName
class
for details of this syntax). In the object name defined by
Main
, name
,
the domain is com.example.mbeans
(the
package in which the example MBeans are contained) and the
key-property declares that this object is of the type Hello
.
An instance of a Hello
object is created, named mbean
. This
Hello
object is itself an instance of
the MBean Hello
that was defined in
Section "MBean
Implementation".
The Hello
object named
mbean
is then registered as an MBean in
the MBean server mbs
with the object
name name
, by passing the object and the
object name into a call to the JMX method MBeanServer.registerMBean()
.
With the Hello
MBean
registered in the MBean server, Main
will simply wait for management operations to be performed on
Hello
. In the scope of this example,
these management operations are invoking sayHello()
, and add()
,
and getting and setting the attribute values.
Having examined the example classes, you can now
run the example. The Java Platform, Standard Edition comes with a
management and monitoring console, named JConsole, that is used to
interact with the MBean in this example. JConsole is located in
JavaSE_HOME/bin/jconsole
, in which JavaSE_HOME is the installation directory of the
Java Platform, Standard Edition (Java SE platform).
To run the example, follow the steps below, or see
the README
file:
/jmx_examples/Essential
.
$
cd work_dir/jmx_examples/Essential
$
javac com/example/mbeans/*.java
Main
application.
$
java com.example.mbeans.Main
You will see confirmation that Main
is waiting for something to happen.
$
jconsole
You will see the JConsole tool open, presenting a list of running JMX agents that you can connect to.
com.example.mbeans.Main
from
the list in the “New Connection” window, and click on
“Connect”.
You will see a summary of your platform’s current activity.
This panel shows you all the MBeans currently registered in the MBean server.
com.example.mbeans
node in the MBean tree.
You will see the example MBean Hello
, that was created and registered by
Main
. If you click on Hello
, you will see its associated Attributes and
Operations nodes in the MBean tree.
Hello
MBean node in the
MBean tree.
The Hello
MBean’s
metadata and its associated Descriptor will be displayed.
Attributes
node of the
Hello
MBean in the MBean tree.
This displays the MBean attributes that were
defined by the Hello
class.
CacheSize
attribute to 150
In the terminal window in which you started
Main
, you will see confirmation of this
change of attribute.
Operations
node of the
Hello MBean in the MBean tree.
Here you will see the two operations declared by
the Hello
MBean, sayHello()
and add()
.
sayHello()
operation, by
clicking on the sayHello
button.
A JConsole dialogue box will inform you that the
method was invoked successfully, and you will see the message
“hello, world” in the
terminal window in which Main
is
running.
add()
operation to add up, and click on the add
button.
You will be informed of the answer in a JConsole dialogue box.
MBeans can generate notifications, for example to signal a state change, a detected event, or a problem.
For an MBean to generate notifications, it must
implement the interface NotificationBroadcaster
, or its subinterface
NotificationEmitter
. All you need to do
to send a notification is to construct an instance of the class
javax.management.Notification
or a
subclass (such as AttributeChangedNotification
), and pass it to
NotificationBroadcasterSupport.sendNotification
.
Every notification has a source. The source is the object name of the MBean that emitted the notification.
Every notification has a sequence number. This number can be used to order notifications coming from the same source when order matters and there is a danger of the notifications being handled in the wrong order. It is all right for the sequence number to be zero, but it is better for it to increment for each notification from a given MBean.
There is an example of a standard MBean that emits
notifications in the directory work_dir/jmx_examples/Notification/com/example/mbeans
. This
example is essentially the same as the example seen in Section "Standard
MBeans", except that the Hello
MBean implements the NotificationBroadcaster
interface.
As stated above, the only difference between this example and the one presented in Section "Standard MBeans" is the fact that the MBean implementation allows for the sending of notifications.
Notifications are activated by implementing the
NotificationBroadcaster
interface, as
shown in CODE EXAMPLE 2-1.
package com.example.mbeans; import javax.management.*; public class Hello extends NotificationBroadcasterSupport implements HelloMBean { public void sayHello() { System.out.println("hello, world"); } public int add(int x, int y) { return x + y; } public String getName() { return this.name; } public int getCacheSize() { return this.cacheSize; } public synchronized void setCacheSize(int size) { int oldSize = this.cacheSize; this.cacheSize = size; System.out.println("Cache size now " + this.cacheSize); Notification n = new AttributeChangeNotification(this, sequenceNumber++, System.currentTimeMillis(), "CacheSize changed", "CacheSize", "int", oldSize, this.cacheSize); sendNotification(n); } @Override public MBeanNotificationInfo[] getNotificationInfo() { String[] types = new String[] { AttributeChangeNotification.ATTRIBUTE_CHANGE }; String name = AttributeChangeNotification.class.getName(); String description = "An attribute of this MBean has changed"; MBeanNotificationInfo info = new MBeanNotificationInfo(types, name, description); return new MBeanNotificationInfo[] {info}; } private final String name = "Reginald"; private int cacheSize = DEFAULT_CACHE_SIZE; private static final int DEFAULT_CACHE_SIZE = 200; private long sequenceNumber = 1; }
As you can see in CODE EXAMPLE 2-1, this
Hello
MBean implementation extends the
NotificationBroadcasterSupport
class,
that itself implements the NotificationEmitter
interface.
The operations and attributes are set in the same
way as before, with the only exception that the cacheSize
attribute’s setter method now
defines a new value oldSize
, which
records the cacheSize
attribute’s
value prior to the set operation.
The notification is constructed from an instance,
n
, of the JMX class AttributeChangeNotification
, which extends
javax.management.Notification
. The
notification is constructed within the definition of the
setCacheSize()
method, from the
following information, that is passed to AttributeChangeNotification
as parameters:
Hello
MBean, represented simply by
this
sequenceNumber
, that is set at 1 and
that increases incrementallycacheSize
oldSize
this.cacheSize
The notification n is then passed to the
NotificationBroadcasterSupport.sendNotification()
method.
Finally, the MBeanNotification
is defined to describe the
characteristics of the different notification instances emitted by
the MBean for a given Java class of notification, which in this
case is AttributeChangeNotification
notifications.
The MBean interface, HelloMBean
, and the JMX agent Main
are identical to those used in the previous
example.
Having examined the example classes, you can now
run the example. This example again uses JConsole to interact with
the Hello
MBean.To run the example,
follow the steps below, or see the README
file:
/jmx_examples/Notification
.
$
cd work_dir/jmx_examples/Notification
$
javac com/example/mbeans/*.java
Main
application.
$
java com.example.mbeans.Main
You will see confirmation that Main
is waiting for something to happen.
$
jconsole
You will see the JConsole tool open, presenting a list of running JMX agents that you can connect to.
com.example.mbeans.Main
from
the list in the “New Connection” window, and click on
“Connect”.
You will see a summary of your platform’s current activity.
This panel shows you all the MBeans currently registered in the MBean server.
com.example.mbeans
node in the MBean tree.
You will see the example MBean Hello
, that was created and registered by
Main
. If you click on Hello
, you will see its associated Attributes
, Operations
and Notifications
nodes in the MBean
tree.
Hello
MBean node in the
MBean tree.
This displays the MBean’s metadata and its associated Descriptor.
Notifications
node of
the Hello MBean in the MBean tree.
You will see that the panel is blank.
The current number of notifications received (0), will be displayed in the Notifications node label.
Attributes
node of the
Hello
MBean in the MBean tree, and
change the value of the CacheSize
attribute to 150
In the terminal window in which you started
Main
, you will see confirmation of this
change of attribute. You will also see that the number of
notifications received displayed in the Notifications node has
changed to 1.
Notifications
node of
the Hello
MBean in the MBean tree again.
You will see the details of the notification that was sent.
An MXBean is a new type of MBean that provides a simple way to code an MBean that only references a pre-defined set of types. In this way, you can be sure that your MBean will be usable by any client, including remote clients, without any requirement that the client have access to model-specific classes representing the types of your MBeans. MXBeans provide a convenient way to bundle related values together without requiring clients to be specially configured to handle the bundles.
In the same way as for standard MBeans, an MXBean
is defined by writing a Java interface called SomethingMXBean
and a Java class that implements that
interface. However, unlike standard MBeans, MXBeans do not require
the Java class to be called Something
.
Every method in the interface defines either an attribute or an
operation in the MXBean. The annotation @MXBean
can be also used to annotate the Java
interface instead of requiring the interface’s name to be
followed by the MXBean suffix.
MXBeans provide a convenient way to bundle related
values together in an MBean without requiring clients to be
specially configured to handle the bundles when interacting with
that MBean. MXBeans already existed in the Java 2 Platform,
Standard Edition (J2SE) 5.0, in the package java.lang.management
. With the Java SE 6 platform,
users can now define their own MXBeans, in addition to the standard
set defined in java.lang.management
.
The key idea behind MXBeans is that types such as
java.lang.management.MemoryUsage
that
are referenced in the MXBean interface, java.lang.management.MemoryMXBean
in this case, are
mapped into a standard set of types, the so-called Open Types that
are defined in the package javax.management.openmbean
. The exact mapping rules
appear in the MXBean specification, but to oversimplify we could
say that simple types like int
or
String
are unchanged, while complex
types like MemoryUsage
get mapped to the
standard type CompositeDataSupport
.
The operation of MXBeans is demonstrated by
example programs that you will find in the directory work_dir/jmx_examples/MXBean/com/example/mxbeans
after you
have downloaded and unzipped the jmx_examples.zip
file. The MXBean example contains
the following files:
QueueSamplerMXBean
interface.QueueSampler
class that implements
the MXBean interface.QueueSample
Java type returned by
the getQueueSample()
method in the
MXBean interface.Main
, the program that sets up and
runs the example.The MXBean example performs the following actions.
type Queue<String>
.getQueueSample
,
in the MXBean that takes a snapshot of the queue when invoked and
returns a Java class QueueSample
that
bundles the following values together:CODE EXAMPLE 2-1 shows the
code of the sample QueueSamplerMXBean
interface.
package com.example.mxbeans; public interface QueueSamplerMXBean { public QueueSample getQueueSample(); public void clearQueue(); }
As you can see, you declare an MXBean interface in
exactly the same way as you declare a standard MBean. The
QueueSamplerMXBean
interface declares
two operations, getQueueSample
and
clearQueue
.
The QueueSampler
class
implements the QueueSamplerMXBean
interface, as shown in CODE EXAMPLE 2-1.
package com.example.mxbeans; import java.util.Date; import java.util.Queue; public class QueueSampler implements QueueSamplerMXBean { private Queue<String> queue; public QueueSampler(Queue<String> queue) { this.queue = queue; } public QueueSample getQueueSample() { synchronized (queue) { return new QueueSample(new Date(), queue.size(), queue.peek()); } } public void clearQueue() { synchronized (queue) { queue.clear(); } } }
The MXBean operations getQueueSample() and
clearQueue() declared by the MXBean interface are defined in
QueueSampler
. The getQueueSample()
operation simply returns an instance of the QueueSample
Java type, created with the values
returned by the java.util.Queue
methods
peek()
and size()
and an instance of java.util.Date.
The QueueSample
instance returned by QueueSampler
is
defined in the QueueSample
class shown
in CODE EXAMPLE 2-1.
package com.example.mxbeans; import java.beans.ConstructorProperties; import java.util.Date; public class QueueSample { private final Date date; private final int size; private final String head; @ConstructorProperties({"date", "size", "head"}) public QueueSample(Date date, int size, String head) { this.date = date; this.size = size; this.head = head; } public Date getDate() { return date; } public int getSize() { return size; } public String getHead() { return head; } }
In QueueSample
class,
the MXBean framework calls all the getters in QueueSample
to convert the given instance into a
CompositeData
and uses the @ConstructorProperties
annotation to reconstruct a
QueueSample
instance from a CompositeData
.
Having defined an MXBean interface and the class
that implements it, as well as the Java type that is returned, the
MXBean must now be created and registered in an MBean server. These
actions are performed by the example class Main
.
package com.example.mxbeans; import java.lang.management.ManagementFactory; import java.util.Queue; import java.util.concurrent.ArrayBlockingQueue; import javax.management.MBeanServer; import javax.management.ObjectName; public class Main { public static void main(String[] args) throws Exception { MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); ObjectName name = new ObjectName("com.example.mxbeans:type=QueueSampler"); Queue<String> queue = new ArrayBlockingQueue<String>(10); queue.add("Request-1"); queue.add("Request-2"); queue.add("Request-3"); QueueSampler mxbean = new QueueSampler(queue); mbs.registerMBean(mxbean, name); System.out.println("Waiting..."); Thread.sleep(Long.MAX_VALUE); } }
The Main
class gets the
platform MBean server, creates an object name for the MXBean
QueueSampler
, creates a Queue
instance for the QueueSampler
MXBean to process, and feeds this Queue
instance to a newly created QueueSampler
MXBean. The MXBean is then registered in the MBean server in
exactly the same way as a standard MBean.
To run the example, follow the steps below, or see
the README
file:
/jmx_examples/MXBean
.
$
cd work_dir/jmx_examples/MXBean
$
javac com/example/mxbeans/*.java
Main
application.
$
java com.example.mxbeans.Main
You will see confirmation that Main
is waiting for something to happen.
$
jconsole
You will see the JConsole tool open, presenting a list of running JMX agents that you can connect to.
com.example.mxbeans.Main
from
the list in the “New Connection” window, and click on
“Connect”.
You will see a summary of your platform’s current activity.
This panel shows you all the MBeans currently registered in the MBean server.
com.example.mxbeans
node in the MBean tree.
You will see the example MBean QueueSampler
, that was created and registered by
Main. If you click on QueueSampler
, you
will see its associated Attributes and Operations nodes in the
MBean tree.
Attributes
node.
You will see the QueueSample
attribute appear in the right-hand pane,
with its value of javax.management.openmbean.CompositeDataSupport
.
CompositeDataSupport
value.
You can see the QueueSample
values date
,
head
and size
because the MXBean framework has converted the QueueSample
instance into CompositeData
. If you had defined QueueSampler
as a Standard MBean rather than as an
MXBean, JConsole would not have found the QueueSample
class because it would not be in its
class path. If QueueSampler
had been a
standard MBean, you would have received a ClassNotFoundException
when retrieving the
QueueSample
attribute value. This
demonstrates the usefulness of using MXBeans when connecting to JMX
agents through generic JMX clients, like JConsole.
Operations
node.
You will see a button to invoke the clearQueue
operation.
clearQueue
button.
You will be informed that the method was invoked successfully.
Attributes
node again and
double click on the CompositeDataSupport
value.
The queue has been reset now.
In this example JConsole has been used as the JMX client but if you were to access your MXBean programmatically in a JMX client you write yourself, then you could do so in one of two ways:
MBeanServer mbs = ...whatever...; ObjectName name = new ObjectName("com.example.mxbeans:type=QueueSampler"); CompositeData queueSample = (CompositeData) mbs.getAttribute(name, "QueueSample"); int size = (Integer) queueSample.get("size");
MBeanServer mbs = ...whatever...; ObjectName name = new ObjectName("com.example.mxbeans:type=QueueSampler"); QueueSamplerMXBean proxy = JMX.newMXBeanProxy(mbs, name, QueueSamplerMXBean.class); QueueSample queueSample = proxy.getQueueSample(); int size = queueSample.getSize();
CODE EXAMPLE 2-2 uses the
newMXBeanProxy method to create the MXBean proxy. An equivalent
method, newMBeanProxy
, exists to create
proxies for other types of MBeans. The newMBeanProxy
and newMXBeanProxy
methods are used in exactly the same
way.
Descriptors allow you to give additional information about MBeans to management clients. For example, a Descriptor on an MBean attribute might say what units it is measured in, or what its minimum and maximum possible values are. As of Java SE 6, Descriptors are an integrated part of the JMX API and are available in all types of MBeans.
Descriptors give you a convenient way to attach arbitrary extra metadata to your MBeans. Descriptors have always existed in the JMX API, but until Java SE 6 they were only available in conjunction with Model MBeans.
For most constructors in the classes MBean*Info
(MBeanInfo
,
MBeanAttributeInfo
, and so on), a
parallel constructor exists with the same parameters plus an
additional javax.management.Descriptor
parameter. The same is true for OpenMBean*InfoSupport
. The MBean*Info
and OpenMBean*InfoSupport
classes contain a getDescriptor()
method.
Open MBeans return information about default and
legal values from the getDefaultValue()
,
getLegalValues()
, getMaxValue()
, getMinValue()
methods of OpenMBeanParameterInfo
and OpenMBeanAttributeInfo
. This information is now also
present in the corresponding Descriptors, and other types of MBean
can also return the information in their Descriptors.
MBean Descriptors are demonstrated in the example
classes you will find in the directory work_dir/jmx_examples/Descriptors/com/example/mxbeans
after
you have downloaded and unzipped the jmx_examples.zip
file. The MBean Descriptor example
contains the following files.
Author
, an annotation the supplies
the name of the author of the MBean interface.DisplayName
, an annotation that
supplies a display name for methods in the MBean interface.Main
, the program that sets up and
runs the example.QueueSamplerMXBean
interface.QueueSampler
class that implements
the MXBean interface.QueueSample
Java type returned by
the getQueueSample()
method in the
MXBean interface.Version
, an annotation that supplies
the current version of the MBean interface.The QueueSampler
MXBean
in this example basically performs the same actions as the MXBean
example presented in Chapter 2,
"Introducing MXBeans", except with the
addition of MBean Descriptors. This example shows how the
DescriptorKey
meta-annotation can be
used to add new descriptor items to the Descriptors for a standard
MBean (or an MXBean) via annotations in the standard MBean (or
MXBean) interface.
A new annotation DescriptorKey
can be used to add information to the
Descriptors for a standard MBean (or MXBean) via annotations in the
Standard MBean (or MXBean) interface. This makes it possible for a
tool that generates standard MBeans from an existing management
model to include information from the model in the generated MBean
interfaces, rather than in separate files.
CODE EXAMPLE 2-1 shows the
definition of the annotation Author
.
package com.example.mxbeans; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import javax.management.DescriptorKey; @Documented @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Author { @DescriptorKey("author") String value(); }
This annotation supplies the name of the creator
of the MBean interface. A new field author
will be added to the MBeanInfo
Descriptor with the value defined by the
@Author
annotation. The files
Version
and DisplayName
define annotations of those names in
exactly the same way as for Author
above. In each of Version
and
DisplayName
, the @DescriptorKey
value is “version”
and “displayname”
respectively.
In the case of Version, a new field version
will be added to the MBeanInfo
Descriptor with the value defined by the
@Version
annotation.
For DisplayName
, new
field displayName
will be added to the
MBeanAttributeInfo
Descriptor or the
MBeanOperationInfo
Descriptor with the
value defined by the @DisplayName
annotation depending on whether the annotated method is a
getter/setter or an operation, respectively.
The QueueSamplerMXBean
interface used in this example is slightly different from the one
used in the MXBeans example, in as much as it implements MBean
Descriptors to publish some of its information.
package com.example.mxbeans; @Author("Mr Bean") @Version("1.0") public interface QueueSamplerMXBean { @DisplayName("GETTER: QueueSample") public QueueSample getQueueSample(); @DisplayName("OPERATION: clearQueue") public void clearQueue(); }
Here, you see that the @Author
annotation is set to Mr.
Bean
, the @Version
annotation is
set to 1.0
, and the @DisplayName
is set to the names either of the
attribute QueueSample
or the operation
clearQueue
.
To run the example, follow the steps below, or see
the README
file:
/jmx_examples/Descriptors
.
$
cd work_dir/jmx_examples/Descriptors
$
javac com/example/mxbeans/*.java
Main
application.
$
java com.example.mxbeans.Main
You will see confirmation that Main
is waiting for something to happen.
$
jconsole
You will see the JConsole tool open, presenting a list of running JMX agents that you can connect to.
com.example.mxbeans.Main
from
the list in the “New Connection” window, and click on
“Connect”.
You will see a summary of your platform’s current activity.
This panel shows you all the MBeans currently registered in the MBean server.
com.example.mxbeans
node in the MBean tree.
You will see the example MBean QueueSampler
, that was created and registered by
Main. If you click on QueueSampler
, you
will see its associated Attributes and Operations nodes in the
MBean tree.You will also see the fields author
and version
in the
MBeanInfo
Descriptor table.
Attributes
and
Operations
nodes under the QueueSampler
MBean node.
You will see the individual Attributes and Operations.
QueueSample
node.
You will see the field displayName
in the MBeanAttributeInfo
Descriptor table.
clearQueue
node.
You will see the field displayName
in the MBeanOperationInfo
Descriptor table.