0

I'm trying to set up a configurable JMX notification listener which allows the user to select an MBean from a list of broadcaster MBeans registered on the platform MBeanServer (ManagementFactory.getPlatformMBeanServer())

mBeanObjectName = new ObjectName(mBeanParameter.stringValue());

notificationListener = new NotificationListener() {
    @Override
    public void handleNotification(Notification notification, Object handback) {
        getLogger().info("Notification received: " + notification);
    }
};

MBeanServer server = ManagementFactory.getPlatformMBeanServer();
server.addNotificationListener(mBeanObjectName, notificationListener, null, null);

As a first test, I tried listening to the garbage collection notifications ("java.lang:type=GarbageCollector,name=PS MarkSweep"). When I trigger a GC using JConsole, my listener's handleNotification method is never called.

I have been going through the code with a debugger, and I don't see anything going wrong with registering my listener to this bean.

So next I registered a simple HelloWorld bean (extending NotificationBroadcasterSupport) with a string attribute. When I listen to this bean and modify the string attribute using JConsole, the handleNotification method is called like expected.

The bean:

public class HelloWorld extends NotificationBroadcasterSupport implements HelloWorldMBean {

    private String greeting = null;

    public HelloWorld() {
        this.greeting = "Hello World!";
    }

    public HelloWorld(String greeting) {
        this.greeting = greeting;
    }

    @Override
    public void setGreeting(String greeting) {
        this.greeting = greeting;

        Notification notification = new Notification("helloworld.test", this, -1, System.currentTimeMillis(), greeting);
        sendNotification(notification);
    }

    @Override
    public String getGreeting() {
        return greeting;
    }
}

Bean registration:

MBeanServer server = ManagementFactory.getPlatformMBeanServer();
server.registerMBean(new HelloWorld(), new ObjectName("Test:name=helloWorld"));

Important to mention is that this runs in an OSGi based application, so I'm starting to think it is a classloader issue.

So a next test was to eliminate the OSGi factor. Surprise suprise, now I do get notifications from the GC MBean..

I've been looking for some way to include my bundle's classloader in the platform MBeanServer but there doesn't seem to be a way to do this. I thought I found something when I stumbled upon the bean server's getClassLoaderRepository method, but the public interface (javax.management.loading.ClassLoaderRepository) doesn't include any methods to add a classloader. And the platform MBeanServer's repository is an instance of com.sun.jmx.mbeanserver.SecureClassLoaderRepository which doesn't allow this either.

I've also tried to set the threadcontext classloader and I've made my notification listener serializable. Didn't do the trick.

So I'm hoping someone can help me out here.

Ynkfish
  • 1
  • 1

1 Answers1

0

It seems like it works after all.
For some unknown reason the debugger just doesn't stop in the handleNotification method and I was mislead due to my logger not printing the 'Notification received' message (changed to System.out.println and it showed up in the console...)

Ynkfish
  • 1
  • 1