OSGi环境中的JMX通知侦听器

时间:2015-05-28 09:08:31

标签: java osgi classloader jmx mbeans

我尝试设置可配置的JMX通知侦听器,允许用户从平台MBeanServer上注册的广播MBean列表中选择MBean( 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);

作为第一个测试,我尝试收听垃圾收集通知(" java.lang:type = GarbageCollector,name = PS MarkSweep ")。 当我使用JConsole触发GC时,永远不会调用我的侦听器的handleNotification方法。

我一直在使用调试器来查看代码,并且我没有看到将我的监听器注册到这个bean的任何问题。

接下来,我使用字符串属性注册了一个简单的HelloWorld bean(扩展NotificationBroadcasterSupport)。 当我使用JConsole监听这个bean并修改string属性时,会调用handleNotification方法,就像预期的那样。

豆子:

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注册:

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

重要的是,这是在基于OSGi的应用程序中运行的,所以我开始认为这是一个类加载器问题。

接下来的测试是消除OSGi因素。 令人惊讶的是,现在我收到来自GC MBean的通知..

我一直在寻找某种方法将我的bundle的类加载器包含在平台MBeanServer中,但似乎没有办法实现这一点。 当我偶然发现bean服务器的getClassLoaderRepository方法时,我以为我找到了一些东西,但是公共接口( javax.management.loading.ClassLoaderRepository )并没有包含任何添加方法的方法。类加载器。平台MBeanServer的存储库是一个实例 com.sun.jmx.mbeanserver.SecureClassLoaderRepository 也不允许这样做。

我还尝试设置threadcontext类加载器,并且我已将通知侦听器序列化。没有做到这一点。

所以我希望有人可以帮助我。

1 个答案:

答案 0 :(得分:0)

毕竟它似乎有效。
由于某些未知原因,调试器不会在handleNotification方法中停止,并且由于我的记录器未打印“收到通知”而导致我误导。消息(更改为System.out.println,它出现在控制台中......)