Standard MBeans
A standard MBean is created by creating an interface that complies with the naming convention of
SomethingMBean. The implementation is then called
Something. A
NotCompliantMBeanException exception will be thrown if this convention is not followed.
Following the naming convention, the standard JavaBean conventions can be followed in terms of getters and setters.
Remote Monitoring
Once the resource has been created by MBeans, the management of that resource is done by a JMX agent. The core component of the JMX agent is the MBean server. The MBean server is a managed object server in which MBeans are registered. A JMX agent also includes a set of services used to manage MBeans.
To create a basic JMX Agent, the following is minimal
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
ObjectName on = new ObjectName("package.location.of.mbeans:type=Example");
Example e = new Example();
mbs.registerMBean(e, on);
Provided the application remains running, you can then fire up
jconsole and monitor the process within there. Under the MBeans tab you should then find
package.location.of.mbeans with a unit below it called Example which can then be observed, called, monitored etc.
Warning
I had some issues getting the small example working on a windows machine. This ended up being a combination of rights access (which I was struggling with on windows) and folders that existed in %TMP%. They had my username including capitals which is correct as far as I know, but they needed deleting and when they were recreated with lowercase they worked fine. You can see evidence of this by having jconsole grayed out on its monitoring processes. There is more on this
here.
I also had issues where i couldn't connect to the weblogic process. This turned out to be a classpath problem which can be solved by using the jconsole of weblogics jrocket jvm. More than on that
here
MXBeans
An MXBean is a type of MBean that references only a predefined set of data types. This allows you to be more flexible in allowing your clients (including remote clients) to use your MBean without allowing them access to more data than they need. The process for creating them is similar to MBeans.
First you must create an interface that either follows the naming convention of
SomethingMXBean, or annotate the interface with @MXBean. Then have a class implement that interface. Unlike MBeans, there is no requirement on the implementation to be called
Something.
The idea behind MXBeans is that types such as
MemoryUsage that are referenced in the MXBean interface
MemoryMXBean are mapped to a set of types known as
Open Types that are defined in the package
javax.management.openmbean. The general principle is for simple types such as
int or
String to remain unchanged, while complex types such as
MemoryUsage get mapped to the standard type
CompositeDataSupport.
MXBeans Example
To create an MXBean interface, almost exactly the same as an MBean example
public interface QueueSamplerMXBean {
public QueueSample getQueueSample();
public void clearQueue();
}
Then the implementation:
public class QueueSampler implements QueueSamplerMXBean {
private Queue queue;
public QueueSampler(Queue queue) {
this.queue = queue;
}
public QueueSample getQueueSample() {
return new QueueSample(new Date(), queue.size(), queue.peek());
}
public void clearQueue() {
queue.clear();
}
}
Then unlike MBeans, we need an additional class for the type.
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;
}
}
The MXBean framework calls all the getters in
QueueSample to convert the given instance into a
CompositeData instance. It uses the
@ConstructorProperties annotation to reconstruct a QueueSample instance from a CompositeData instance.
Registering the MXBean is much the same as registering an MBean, however in this case the difference is we need to construct the queue system before we can use it. We register the
QueueSampler class against the MBean server and don't actually reference the returned type in our calling code.
Notifications
The model for adding notification support is actually quite simple. When you create the implementation of your MBean, you will want to extend somewhere in your hierarchy the class
NotificationBroadcasterSupport and where you want to create notifications simple instantiate a subclass of
Notification such as the pre-existing
AttributeChangeNotification. Once constructed it can be passed to sendNotification().
After adding this support, you will have the ability to subscribe to notifications from tools such as jconsole.
Related resources
Oracle JMX Trail
wiki MBeans
MBean Server interface