Table of Contents
Each MBean object needs a unique identifier in the MBeanSever,
of course.
That identifier is called the MBean Name,
and consists of the JMX Domain and key/value pairs.
The whole thing is formatted like
DomainName:key1=val1,key2=val2.
The Java class javax.management.ObjectName represents an MBean
Name (as well as a wild-card for MBean Names).
The entire combination of the domain plus all keys and values
must be unique.
(That is equivalent to saying that the entire MBean Name must
be unique).
Once you implement an MBean by any of the methods in the Instrumentation chapter of this doc, then you can use a JMX Client to work with them as MBeans (I'm only describing how to use them as MBeans. There is nothing to prevent you from accessing the classes directly instead of through JMX-- but this Howto is about JMX). A JMX Client can instantiate, interrogate, register, retrieve and invoke methods on MBeans. If a JMX Client program has an interface for non-JMX clients, then you can use a non JMX program, like a web browser or the command line, to work with MBeans via the JMX Client (JMX Clients that perform this function are called Adaptors. The first thing we do in the Instrumentation chapter is start up an Adaptor). There are additional, non-essential features useful in specific problem domains. I list these in the JMX Features chapter.
When you implement any kind of MBean, you (usually) have to
tell the JMX system which methods to expose-- because you
don't generally want to expose all of them.
(The exception to this is with constructors, as I explain next).
I call this publishing.
If you publish method X.y()
, then method X.y()
will be available to JMX Clients who get access to MBeans for
the class X. JMX divides published methods are divided into
three groups.
MBean Published Method Types
Constructor methods. Constructor usage was designed very poorly in JMX. The problem is that MBeans can only be interrogated after they are instantiated. So, before you instantiate the first instance of MBean of class C, you can not use JMX to interrogate class C. Instead of providing a way to interrogate MBean classes before instantiation,
JMX Clients must use normal Java reflection to find the public constructors for the desired MBean class. As a result, there is no way to see the JMX constuctor descriptions if the MBean developer has provided them.
JMX constructor information provided by the MBean developer is used by a JMX Client only when the JMX Client queries an existing, instantiated MBean of the same type.
JMX will use any public constructor for an MBean requested by a JMX Client, regardless of whether the MBean developer has told JMX to expose them.
To restate the confusing results of this.
JMX Clients can always see all of the public constructors of an MBean using normal Java reflection.
If a JMX Client uses JMX to view the public constructors (you can only do with on an existing MBean), it will only see those that have been exposed through JMX methods.
Whether a JMX Client can see public MBean constructors through JMX interrogation or not, it can use JMX to instantiate new MBeans using any public constructor.
Notice that all of this makes constructor descriptions pretty close to useless. It is impossible for a JMX Client to use constructor descriptions when they are most important-- before the first MBean of the class is instantiated.
These are just getter/setter and/or is methods, just like for traditional Java Beans (e.g., getX(), setX(y), isX()). You can't overload setters. Getters/is methods only work with no arguments at all. You should not use both a getter and an is-- it's one or the other.
N.b. that methods of the form getX(arg1) and setY(arg1, arg2) can only be exposed as operations, since getters must be of the form getX() (i.e. no arguments), and setters must be of the form setY(arg1) (i.e. one argument).
All remaining methods. You should not overload operations (according to the Spec). There is nothing to prevent you from exposing a getter/setter/is method as an operation instead of an attribute-- just don't do both!
mbeanServerConnection.method(mbeanID,
"mbeanMethodName",..., not like
mbean.mbeanMethodName(...).
(The latter is possible with a MX4J delegation feature which
works just like Axis delegation stubs for SOAP).
According to the JMX Spec, and common sense, you pretty much never want to change the JMX Interface of MBeans dynamically. JMX always sets up the original interface of an MBean class dynamically (even though with Standard MBeans this is hidden from you). To dynamically change the exposed MBean Interface, you would need to make very complex registration, tracking and notification strategies so that the JVM knows which version of the published methods to use for which MBean instances. A true nighmare. In practice, the coding needed just for one-time dynamic MBean interface setup is extremely complex, and you are hereby advised to try to avoid doing that work (some strategies are recommended below). The main point is, it does not makes sense to modify an MBean's published interface dynamically.
The main division of MBeans is between Standard and Dynamic. Both Standard and Dynamic MBeans dynamically publish their JMX interfaces. With Dynamic MBeans, you code the methods to publish your methods. With Standard MBeans, the JMX libraries use reflection on your class to publish the methods for you. Dynamic MBeans additionally provide for runtime modification of the JMX interface-- just what Sun recommends against.
For the class to expose, you use a naming convention for the methods to expose, then put the signature of those methods into a new interface (the MBean Interface) which follows a naming convention. (I.e., the MBean Interface interface name is not MBean, but follows a naming convention). JMX uses reflection to publish the exposed methods at the right time. This is all done very similarly to how traditional Java Beans work.
Unfortunately, Sun decided to not support publishing descriptions for Standard MBeans and their exposed methods.
Dynamic MBeans can publish a description for each exposed method. IMO, this is the best feature that there is to JMX. Your end users can use a generic interface to browse existing MBeans which themselves tell the user how to use them.
Varieties of Dynamic MBeans
You code a few methods to satisfy the DynamicMBean interface. Unfortunately, these methods must assemble ugly, overly-nested objects. Most of these methods return different combinations of the same static information all the time-- if they do not, you will have the fiasco explained in the first paragraph in the MBean Types: Standard vs. Dynamic section.
Hand-made Dynamic MBeans are a horrific thing. I highly recommend that if you want to use traditional Dynamic MBeans or Open MBeans, you make use of AbstractDynamicMBeans.
An Open MBean is just a Dynamic MBean that follows some conventions which makes it less powerful and convenient, but more portable. An Open MBean implements the DynamicMBean interface. The basic idea is that if you stick to using primitive data types and the basic Java-defined and JMX-defined classes, then all of this data can be passed without needing anything else in the classpath, and there is never any possibility of version conflicts of outside classes. (Maybe some day they will make a VeryOpen MBean that can only use String objects. Since every version of every JVM can handle compatible Strings, and every other class can be converted to and from a String, VeryOpen MBeans would be more portable than Open MBeans.)
Developing Dynamic MBeans and OpenMBeans is straight forward in that you code methods in the class that you want to expose (though, as explained, those methods are ugly and difficult). With Model MBeans, you do not code in the class file that you want to expose. You use a factory to instantiate an empty Model Mbean, then tell that Model MBean what methods to expose (these methods can be from any accessible classes). So, you do not have a .java file that is a Model MBean, you get a Model MBean from the JMX implementation and work with it. (Just like you usually don't have a .java file that is a Properties. You retrieve or instantiate a Properties instance and work with it.)
AbstractDynamicMBean is a class implementing Dynamic
MBean (whereas an Open MBean is a subset of Dynamic
MBean classes and a Model MBean is an interface that
extends DynamicMBean).
AbstractDynamicMBean is provided by MX4J.
To use it with a JMX implementation other than MX4J,
you just include the following two classes to your
CLASSPATH: jmx.utils.Util,
jmx.AbstractDynamicMBean.
You can obtain these classes from any
mx4j-impl.jar,
mx4j.jar, or my own
http://admc.com/dist/admcjmx-adaptors.jar.
AbstractDynamicMBeans, unlike traditional DynamicMBeans, are easy to understand by example. In the Instrumentation chapter of this document, I provide detailed, documented examples.