Send notification at MBean attribute change
This is an example of how to send a notification when an attribute of an MBean changes. An MBean is a managed Java object, similar to a JavaBeans component, that follows the design patterns set forth in the JMX specification. An MBean can represent a device, an application, or any resource that needs to be managed. MBeans expose a management interface that consists of a set of readable or writable attributes, or both, a set of invokable operations and a self-description. The JMX API also defines a mechanism to enable MBeans to generate notifications, for example, to signal a state change, a detected event, or a problem. Here, we will create an MBean and register it to MBeanServer, and then generate a notification when an attribute of the MBean changes. In short, the steps we will follow are:
- Create a Java interface,
HelloBean
. Every method in the interface defines either an attribute or an operation in the MBean. The interface has a method,sayHello()
a read-write attribute calledmessage
of type String. This is the attribute on whose change we will send the notification. - Create a Java class,
Hello
that implements that interface and also extends NotificationBroadcasterSupport so as to be able to generate notifications. In its constructor it usesaddNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback)
API method of NotificationBroadcasterSupport, so as to add a listener. In this method it overrides thehandleNotification(NotificationListener listener, Notification notif, Object handback)
method of NotificationBroadcasterSupport, where it prints the notification it handles. The notification has a source that is the name of the MBean, and we can get it usinggetMessage()
Notification API method and it also has a sequence number that we can get usinggetSequenceNumber()
Notification API method. In thesetMessage(String message)
method, the old message is held in a variable and then a new AttributeChangeNotification is created for the new message, increasing the sequence number of notifications and then thesendNotification(Notification notification)
API method of NotificationBroadcasterSupport is used to send the notification. - Create an MBeanServer that is the interface for MBean manipulation on the agent side. Use
getPlatformMBeanServer()
API method of ManagementFactory. - Define the object name for the MBean. The object name is an instance of the JMX class ObjectName and must contain a domain and a list of key-properties.
- Create a new instance of the MBean and register it to MBeanServer, using
registerMBean(Object object, ObjectName name)
API method of MBeanServer. - Use
getAttribute(ObjectName name, String attribute)
API method of MBeanServer to get the value of a specific attribute of the MBean. - Use
setAttribute(ObjectName name, Attribute attribute)
API method of MBeanServer to change the value of the same attribute of the MBean and then get the attribute’s value again.
Let’s take a look at the code snippet that follows:
package com.javacodegeeks.snippets.enterprise; import java.lang.management.ManagementFactory; import javax.management.Attribute; import javax.management.AttributeChangeNotification; import javax.management.MBeanServer; import javax.management.Notification; import javax.management.NotificationBroadcasterSupport; import javax.management.NotificationListener; import javax.management.ObjectName; public class SendNotificationAtMBeanAttributeChange { public static void main(String[] args) throws Exception { String objectName = "com.javacodegeeks.snippets.enterprise:type=Hello"; MBeanServer server = ManagementFactory.getPlatformMBeanServer(); // Construct the ObjectName for the Hello MBean we will register ObjectName mbeanName = new ObjectName(objectName); Hello mbean = new Hello(); server.registerMBean(mbean, mbeanName); // print the default message String currentMessage = (String) server.getAttribute(mbeanName, "Message"); System.out.println("Current Message: " + currentMessage); // change the attribute value String newMessage = "Hello Java Code Geeks"; server.setAttribute(mbeanName, new Attribute("Message", newMessage)); // print the new message currentMessage = (String) server.getAttribute(mbeanName, "Message"); System.out.println("Current Message: " + currentMessage); } public static class Hello extends NotificationBroadcasterSupport implements HelloMBean { private long sequenceNumber = 1; private String message = "Hello World"; public Hello() { addNotificationListener(new NotificationListener() { @Override public void handleNotification(Notification notification, Object handback) { System.out.println("*** Handling new notification ***"); System.out.println("Message: " + notification.getMessage()); System.out.println("Seq: " + notification.getSequenceNumber()); System.out.println("*********************************"); } }, null, null); } @Override public String getMessage() { return this.message; } @Override public void sayHello() { System.out.println(message); } @Override public void setMessage(String message) { String oldMessage = this.message; this.message = message; Notification n = new AttributeChangeNotification(this, sequenceNumber++, System.currentTimeMillis(), "Message changed", "Message", "String", oldMessage, this.message); sendNotification(n); } } public static interface HelloMBean { // operations public void sayHello(); // attributes // a read-write attribute called Message of type String public String getMessage(); public void setMessage(String message); } }
This was an example of how to send a notification when an attribute of an MBean changes in Java.