JDK-6450834 : RFE: allow StandardMBean to call MBeanRegistration methods on its wrapped resource
  • Type: Enhancement
  • Component: core-svc
  • Sub-Component: javax.management
  • Affected Version: 6
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2006-07-20
  • Updated: 2017-05-16
  • Resolved: 2011-04-19
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
7 b43Fixed
The class javax.management.StandardMBean implements MBeanRegistration as of Mustang.  But if you have a StandardMBean constructed as new StandardMBean(impl, SomethingMBean.class), and if the impl object itself implements MBeanRegistration, the MBeanRegistration methods are not forwarded to impl as you might expect.  This is for compatibility reasons: it would have changed the behaviour of existing code.

We could have a way of creating a StandardMBean or StandardEmitterMBean that explicitly asks for MBeanRegistration methods to be forwarded to the impl object.

EVALUATION The proposed solution to the problem of .setImplementation is simply to say that this method is not allowed on a StandardMBean instance where the MBeanRegistration option has been set. The proposed way of setting this option is through a new nested class StandardMBean.Options, which is a subclass of another new nested class JMX.MBeanOptions containing other options.

EVALUATION One wrinkle here is the StandardMBean.setImplementation method. Does this method cause MBeanRegistration.preRegister and .postRegister to be called on the wrapped object? Does it cause .preDeregister and .postDeregister to be called on the previous wrapped object?

EVALUATION On the other hand we could add an additional MBeanRegistration parameter instead of a boolean: <T> StandardMBean(T impl, Class<T> clazz, MBeanRegistration regDelegate) { Then the logic would be: preRegister(...) { ... if (regDelegate != this && regDelegate != null) regName = regDelegate.preRegister(...); ... } }

WORK AROUND Subclass StandardMBean and/or StandardEmitterMBean and override the MBeanRegistration methods, like this: public class RegistrableStandardMBean extends StandardMBean { public <T> RegistrableStandardMBean(T impl, Class<T> intf) { super(impl, intf, false); } @Override public ObjectName preRegister(MBeanServer mbs, ObjectName name) { name = super.preRegister(mbs, name); Object impl = getImplementation(); if (impl instanceof MBeanRegistration) return ((MBeanRegistration) impl).preRegister(mbs, name); return name; } ...likewise for the other MBeanRegistration methods... }

EVALUATION We don't want to add yet more boolean parameters to the constructors, so it looks as if we should have some other way of specifying this and other options. Either a Map<String,?> parameter, or perhaps a nested StandardMBean.Options class that you can instantiate and pass to the constructor. Like this: public class StandardMBean { public static class Options implements Cloneable { public Options() {} public Options mxbean(boolean m) { Options clone = clone(); clone.mxbean = m; return clone; } public Options forwardMBeanRegistration(boolean f) {...} public Options clone() {return super.clone();} } public <T> StandardMBean(T impl, Class<T> intf, Options opts) {...} } Used like this: StandardMBean.Options opts = new StandardMBean.Options().mxbean(true).forwardMBeanRegistration(true); StandardMBean mbean = new StandardMBean(myImpl, MyMBean.class, opts);