Search code examples
javajmxmbeans

Detecting newly registered MBeans


I'm using the platform MBeans server in Java 1.6, running in an OSGi container.

Using the MBeans for statistic counters and events mainly. The implementation of them are in one bundle, but they're instantiated in several other bundles. Every MBean autoregisters itself with the platform MBean server.

The problem is that when I attach via JMX and query for MBeans, I only get the ones that are currently registered, and they wont be registered until they've been instantiated (either because static classes don't exist until first access, or because the bundle hasn't started yet, or the counter is deep in some logic that wont exist until first use)

I need some way of subscribing to "register" events in the MBeans server. Or some other way of determining when there are new MBeans added to the server. Detecting removed MBeans would be an added bonus, but not necessary.

The only solution I've got is basically a thread that polls the server every 5 seconds and compares the result with a saved list of MBeans, and that is quite ugly.


Solution

  • All compliant MBeanServers will notify listeners of MBean registration and unregistration events. The key is to register a notification listener on the MBeanServerDelegate.

    For example, a javax.management.NotificationListener implementation:

    public class MBeanEventListener implements NotificationListener {
        public void handleNotification(Notification notification, Object handback) {
            MBeanServerNotification mbs = (MBeanServerNotification) notification;
            if(MBeanServerNotification.REGISTRATION_NOTIFICATION.equals(mbs.getType())) {
                log("MBean Registered [" + mbs.getMBeanName() + "]");
            } else if(MBeanServerNotification.UNREGISTRATION_NOTIFICATION.equals(mbs.getType())) {
                log("MBean Unregistered [" + mbs.getMBeanName() + "]");
            }
        }       
    }
    

    To register the listener, add the notification listener against the MBeanServerDelegate. You can use an MBeanServerNotificationFilter if you want to filter which MBeans you are actually notified about. In this example, the filter is enabled for all ObjectNames.

        // Get a reference to the target MBeanServer
        MBeanServerConnection server = ManagementFactory.getPlatformMBeanServer();
        MBeanServerNotificationFilter filter = new MBeanServerNotificationFilter();
        filter.enableAllObjectNames();
        server.addNotificationListener(MBeanServerDelegate.DELEGATE_NAME, new MBeanEventListener(), filter, null);
    

    Your listener implementation will get a callback every time an MBean is registered or unregistered.