Skip to main content

Adding Descriptors to MBeans in Mustang

Posted by emcmanus on October 22, 2005 at 9:41 AM PDT

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 Mustang
(Java SE 6), Descriptors are a basic part of the JMX API and are
available in all types of MBeans. Here's the easiest way to
use them.

Mustang makes it very convenient to add information to an
MBean. You can use annotations in a Standard MBean to define
the Descriptor contents. For example, with this definition...

@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Units {
    @DescriptorKey("units")
    String value();
}

...you can define an annotation @Units that you
can then use like this...

public interface CacheMBean {
    @Units("whatsits")
    public int getUsed();
}

You can just cut-and-paste the @-infested text that defines
@Units from the

DescriptorKey documentation
, so you don't
need to remember all the details. Of course, as soon as you've
defined @Units once you can use it in any number of
MBeans.

As usual with Standard MBeans, you can make an MBean by
defining a class Cache that implements
CacheMBean and registering it in the MBean Server
something like this...

MBeanServer mbeanServer = href="http://download.java.net/jdk6/docs/api/java/lang/management/ManagementFactory.html#getPlatformMBeanServer()">[prettify]ManagementFactory.getPlatformMBeanServer()
; ObjectName name = new ObjectName("com.example.domain:type=Cache,name="Whatever""); Cache cache = ...whatever...; mbeanServer.registerMBean(name, cache); [/prettify]

Now you can see the units of the Used
attribute defined by the getUsed() method in
the interface...

MBeanInfo mbeanInfo = mbeanServer.getMBeanInfo(name);
for (MBeanAttributeInfo a : mbeanInfo.getAttributes()) {
    Descriptor d = a.getDescriptor();
    System.out.println("Attribute " + a.getName() + " has units " +
       d.getFieldValue("units"));
}

...and as expected this will print...

Attribute Used has units whatsits

If the Descriptor doesn't contain a value for
"units", then the getFieldValue()
method will return null. The
MBeanAttributeInfo.getDescriptor() method never
returns null, though it might return an empty Descriptor.

You can imagine that a management console such as
href="http://java.sun.com/developer/technicalArticles/J2SE/jconsole.html">
jconsole
might use this kind of code to add a label to a graph of the
Used attribute. The as-yet fanciful picture
here shows the units, minValue, and
maxValue items that have been added to the
Descriptor for Used, and the graph that a console
might produce of the Used value over time. The
label of the graph and the minimum and maximum values come from
the Descriptor items.

Graph of Used attribute with labels from Descriptor contents src="http://weblogs.java.net/blog/emcmanus/graphshot.gif"
width="934" height="524" />

This picture comes from my

session
at this year's JavaOne. Sessions are now online
for free!

If you're unable to migrate to Mustang just yet, I have a later blog
entry describing
how to use descriptors with Tiger
and earlier
versions of the J2SE platform.

Related Topics >>