【发布时间】:2015-08-10 16:40:12
【问题描述】:
我正在尝试设置一个可配置的 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)。 当我监听这个 bean 并使用 JConsole 修改字符串属性时,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 的通知..
我一直在寻找某种方法将我的包的类加载器包含在平台 MBeanServer 中,但似乎没有办法做到这一点。 当我偶然发现 bean 服务器的 getClassLoaderRepository 方法时,我以为我发现了一些东西,但是公共接口 (javax.management.loading.ClassLoaderRepository) 不包含任何添加类加载器的方法。平台 MBeanServer 的存储库是 com.sun.jmx.mbeanserver.SecureClassLoaderRepository 这也不允许。
我还尝试设置 threadcontext 类加载器,并使通知侦听器可序列化。没有成功。
所以我希望有人可以在这里帮助我。
【问题讨论】:
标签: java osgi classloader jmx mbeans