Reputation: 5328
I have an MXBean instance which is registered in 2 MBean servers:
@MXBean(true)
public interface I {
// ...
}
public final class C extends StandardMBean implements I {
public C() {
super(I.class, JMX.isMXBeanInterface(I.class));
}
public static void main(final String args[]) throws JMException, IOException {
final MBeanServer mBeanServer0 = ManagementFactory.getPlatformMBeanServer();
final MBeanServer mBeanServer1 = MBeanServerFactory.createMBeanServer();
final ObjectName objectName = new ObjectName("com.example:name=Foo,type=Bar");
final I i = new C();
mBeanServer0.registerMBean(i, objectName);
mBeanServer1.registerMBean(i, objectName);
// ...
}
}
The StandardMBean
instance wraps an instance of MXBeanSupport
. I want to unregister my MBean from both servers later on:
mBeanServer1.unregisterMBean(objectName);
mBeanServer0.unregisterMBean(objectName);
The problem is, unregister()
method of MXBeanSupport
has the following implementation and obviously can only be called once:
@Override
public void unregister() {
synchronized (lock) {
if (mxbeanLookup != null) {
if (mxbeanLookup.removeReference(objectName, getResource()))
objectName = null;
}
}
}
Otherwise, I'm getting an NPE wrapped into a RuntimeMBeanException
:
Exception in thread "main" javax.management.RuntimeMBeanException: RuntimeException thrown in postDeregister method: rethrowing <java.lang.NullPointerException>, although the MBean is sucessfully unregistered
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.postDeregisterInvoke(DefaultMBeanServerInterceptor.java:1060)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.exclusiveUnregisterMBean(DefaultMBeanServerInterceptor.java:452)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.unregisterMBean(DefaultMBeanServerInterceptor.java:415)
at com.sun.jmx.mbeanserver.JmxMBeanServer.unregisterMBean(JmxMBeanServer.java:546)
at com.example.C.main(C.java:41)
Caused by: java.lang.NullPointerException
at com.sun.jmx.mbeanserver.MXBeanLookup.removeReference(MXBeanLookup.java:159)
at com.sun.jmx.mbeanserver.MXBeanSupport.unregister(MXBeanSupport.java:169)
at javax.management.StandardMBean.postDeregister(StandardMBean.java:1137)
at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.postDeregisterInvoke(DefaultMBeanServerInterceptor.java:1054)
... 4 more
Still, unregistering an MBean from a single server only is not an option.
How should I correct my code w/o creating two separate MBean instances?
Upvotes: 1
Views: 478
Reputation: 24336
It appears as though MBeans
are global based on the name, so therefore you would not ever be able to register from a "single instance" and instead you would un-register from all available contexts.
mBeanServer1.unregisterMBean(objectName);
mBeanServer0.unregisterMBean(objectName); // this call is superfluous
Upvotes: 0