6450834: RFE: allow StandardMBean to call MBeanRegistration methods on its wrapped resource
6373143: MonitorNotification should have a public constructor
Reviewed-by: emcmanus
--- a/jdk/src/share/classes/javax/management/StandardMBean.java Tue Dec 09 15:57:09 2008 +0100
+++ b/jdk/src/share/classes/javax/management/StandardMBean.java Tue Dec 09 16:14:53 2008 +0100
@@ -135,6 +135,7 @@
private static final long serialVersionUID = 5107355471177517164L;
private boolean wrappedVisible;
+ private boolean forwardRegistration;
/**
* <p>Construct an {@code Options} object where all options have
@@ -177,15 +178,56 @@
this.wrappedVisible = visible;
}
- // Canonical objects for each of (MXBean,!MXBean) x (WVisible,!WVisible)
+ /**
+ * <p>Defines whether the {@link MBeanRegistration MBeanRegistration}
+ * callbacks are forwarded to the wrapped object.</p>
+ *
+ * <p>If this option is true, then
+ * {@link #preRegister(MBeanServer, ObjectName) preRegister},
+ * {@link #postRegister(Boolean) postRegister},
+ * {@link #preDeregister preDeregister} and
+ * {@link #postDeregister postDeregister} methods are forwarded
+ * to the wrapped object, in addition to the behaviour specified
+ * for the StandardMBean instance itself.
+ * The default value is false for compatibility reasons, but true
+ * is a better value for most new code.</p>
+ *
+ * @return true if the <code>MBeanRegistration</code> callbacks
+ * are forwarded to the wrapped object.
+ */
+ public boolean isMBeanRegistrationForwarded() {
+ return this.forwardRegistration;
+ }
+
+ /**
+ * <p>Set the
+ * {@link #isMBeanRegistrationForwarded MBeanRegistrationForwarded}
+ * option to the given value.</p>
+ * @param forward the new value.
+ */
+ public void setMBeanRegistrationForwarded(boolean forward) {
+ this.forwardRegistration = forward;
+ }
+
+ // Canonical objects for each of
+ // (MXBean,!MXBean) x (WVisible,!WVisible) x (Forward,!Forward)
private static final Options[] CANONICALS = {
new Options(), new Options(), new Options(), new Options(),
+ new Options(), new Options(), new Options(), new Options(),
};
static {
CANONICALS[1].setMXBeanMappingFactory(MXBeanMappingFactory.DEFAULT);
CANONICALS[2].setWrappedObjectVisible(true);
CANONICALS[3].setMXBeanMappingFactory(MXBeanMappingFactory.DEFAULT);
CANONICALS[3].setWrappedObjectVisible(true);
+ CANONICALS[4].setMBeanRegistrationForwarded(true);
+ CANONICALS[5].setMXBeanMappingFactory(MXBeanMappingFactory.DEFAULT);
+ CANONICALS[5].setMBeanRegistrationForwarded(true);
+ CANONICALS[6].setWrappedObjectVisible(true);
+ CANONICALS[6].setMBeanRegistrationForwarded(true);
+ CANONICALS[7].setMXBeanMappingFactory(MXBeanMappingFactory.DEFAULT);
+ CANONICALS[7].setWrappedObjectVisible(true);
+ CANONICALS[7].setMBeanRegistrationForwarded(true);
}
@Override
MBeanOptions[] canonicals() {
@@ -195,7 +237,8 @@
@Override
boolean same(MBeanOptions opts) {
return (super.same(opts) && opts instanceof Options &&
- ((Options) opts).wrappedVisible == wrappedVisible);
+ ((Options) opts).wrappedVisible == wrappedVisible &&
+ ((Options) opts).forwardRegistration ==forwardRegistration);
}
}
@@ -477,7 +520,9 @@
*
* @exception IllegalArgumentException if the given
* <var>implementation</var> is null.
- *
+ * @exception IllegalStateException if the
+ * {@link Options#isMBeanRegistrationForwarded MBeanRegistrationForwarded}
+ * option is true.
* @exception NotCompliantMBeanException if the given
* <var>implementation</var> does not implement the
* Standard MBean (or MXBean) interface that was
@@ -490,6 +535,12 @@
if (implementation == null)
throw new IllegalArgumentException("implementation is null");
+
+ if(options instanceof Options &&
+ ((Options) options).isMBeanRegistrationForwarded())
+ throw new IllegalStateException("Implementation can't be changed " +
+ "because MBeanRegistrationForwarded option is true");
+
setImplementation2(implementation);
}
@@ -1273,10 +1324,14 @@
* registered in the MBean server.</p>
*
* <p>The default implementation of this method returns the {@code name}
- * parameter. It does nothing else for
- * Standard MBeans. For MXBeans, it records the {@code MBeanServer}
- * and {@code ObjectName} parameters so they can be used to translate
- * inter-MXBean references.</p>
+ * parameter. If the
+ * {@link Options#isMBeanRegistrationForwarded MBeanRegistrationForwarded}
+ * option is set to true, then this method is forwarded to the object
+ * returned by the {@link #getImplementation getImplementation()} method.
+ * The name returned by this call is then returned by this method.
+ * It does nothing else for Standard MBeans. For MXBeans, it records
+ * the {@code MBeanServer} and {@code ObjectName} parameters so they can
+ * be used to translate inter-MXBean references.</p>
*
* <p>It is good practice for a subclass that overrides this method
* to call the overridden method via {@code super.preRegister(...)}.
@@ -1311,6 +1366,11 @@
*/
public ObjectName preRegister(MBeanServer server, ObjectName name)
throws Exception {
+ // Forward preRegister before to call register and
+ // inject parameters.
+ if(shouldForwardMBeanRegistration())
+ name = ((MBeanRegistration)getImplementation()).
+ preRegister(server, name);
mbean.register(server, name);
MBeanInjector.inject(mbean.getWrappedObject(), server, name);
return name;
@@ -1320,7 +1380,11 @@
* <p>Allows the MBean to perform any operations needed after having been
* registered in the MBean server or after the registration has failed.</p>
*
- * <p>The default implementation of this method does nothing for
+ * <p>If the
+ * {@link Options#isMBeanRegistrationForwarded MBeanRegistrationForwarded}
+ * option is set to true, then this method is forwarded to the object
+ * returned by the {@link #getImplementation getImplementation()} method.
+ * The default implementation of this method does nothing else for
* Standard MBeans. For MXBeans, it undoes any work done by
* {@link #preRegister preRegister} if registration fails.</p>
*
@@ -1338,16 +1402,24 @@
public void postRegister(Boolean registrationDone) {
if (!registrationDone)
mbean.unregister();
+ if(shouldForwardMBeanRegistration())
+ ((MBeanRegistration)getImplementation()).
+ postRegister(registrationDone);
}
/**
* <p>Allows the MBean to perform any operations it needs before
* being unregistered by the MBean server.</p>
*
- * <p>The default implementation of this method does nothing.</p>
+ * <p>If the
+ * {@link Options#isMBeanRegistrationForwarded MBeanRegistrationForwarded}
+ * option is set to true, then this method is forwarded to the object
+ * returned by the {@link #getImplementation getImplementation()} method.
+ * Other than that, the default implementation of this method does nothing.
+ * </p>
*
* <p>It is good practice for a subclass that overrides this method
- * to call the overridden method via {@code super.preDeegister(...)}.</p>
+ * to call the overridden method via {@code super.preDeregister(...)}.</p>
*
* @throws Exception no checked exceptions are throw by this method
* but {@code Exception} is declared so that subclasses can override
@@ -1356,13 +1428,19 @@
* @since 1.6
*/
public void preDeregister() throws Exception {
+ if(shouldForwardMBeanRegistration())
+ ((MBeanRegistration)getImplementation()).preDeregister();
}
/**
* <p>Allows the MBean to perform any operations needed after having been
* unregistered in the MBean server.</p>
*
- * <p>The default implementation of this method does nothing for
+ * <p>If the
+ * {@link Options#isMBeanRegistrationForwarded MBeanRegistrationForwarded}
+ * option is set to true, then this method is forwarded to the object
+ * returned by the {@link #getImplementation getImplementation()} method.
+ * The default implementation of this method does nothing else for
* Standard MBeans. For MXBeans, it removes any information that
* was recorded by the {@link #preRegister preRegister} method.</p>
*
@@ -1375,8 +1453,15 @@
*/
public void postDeregister() {
mbean.unregister();
+ if(shouldForwardMBeanRegistration())
+ ((MBeanRegistration)getImplementation()).postDeregister();
}
+ private boolean shouldForwardMBeanRegistration() {
+ return (getImplementation() instanceof MBeanRegistration) &&
+ (options instanceof Options &&
+ ((Options) options).isMBeanRegistrationForwarded());
+ }
//
// MBeanInfo immutability
//
--- a/jdk/src/share/classes/javax/management/monitor/MonitorNotification.java Tue Dec 09 15:57:09 2008 +0100
+++ b/jdk/src/share/classes/javax/management/monitor/MonitorNotification.java Tue Dec 09 16:14:53 2008 +0100
@@ -201,7 +201,7 @@
* @param derGauge The derived gauge.
* @param trigger The threshold/string (depending on the monitor type) that triggered the notification.
*/
- MonitorNotification(String type, Object source, long sequenceNumber, long timeStamp, String msg,
+ public MonitorNotification(String type, Object source, long sequenceNumber, long timeStamp, String msg,
ObjectName obsObj, String obsAtt, Object derGauge, Object trigger) {
super(type, source, sequenceNumber, timeStamp, msg);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/monitor/InstantiateMonitorNotificationTest.java Tue Dec 09 16:14:53 2008 +0100
@@ -0,0 +1,52 @@
+
+import javax.management.ObjectName;
+import javax.management.monitor.MonitorNotification;
+
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6373143
+ * @summary Test MonitorNotification public constructor
+ * @author JFDenise
+ * @run clean InstantiateMonitorNotificationTest
+ * @run build InstantiateMonitorNotificationTest
+ * @run main InstantiateMonitorNotificationTest
+ */
+
+public class InstantiateMonitorNotificationTest {
+
+ public static void main(String[] args) throws Exception {
+ MonitorNotification notif = new MonitorNotification("com.foo.test",
+ ObjectName.valueOf(":type=Monitor"),
+ 999,
+ 999,
+ "A message",
+ ObjectName.valueOf(":type=Observed"),
+ "MyAttribute",
+ Integer.valueOf(14),
+ Integer.valueOf(15));
+ System.out.println("Test passed");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/standardmbean/RegistrationTest.java Tue Dec 09 16:14:53 2008 +0100
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6450834
+ * @summary Forward MBeanRegistration calls
+ * @author JF Denise
+ * @run main RegistrationTest
+ */
+
+import java.io.Serializable;
+import java.lang.management.ManagementFactory;
+import javax.management.*;
+
+public class RegistrationTest {
+ static boolean preRegisterCalled;
+ static boolean postRegisterCalled;
+ static boolean preDeregisterCalled;
+ static boolean postDeregisterCalled;
+
+ static void checkResult(boolean expected) throws Exception {
+ if((preRegisterCalled != expected ||
+ postRegisterCalled != expected ||
+ preDeregisterCalled != expected ||
+ postDeregisterCalled != expected))
+ throw new Exception("Mismatch preRegisterCalled = "
+ + preRegisterCalled + ", postRegisterCalled = "
+ + postRegisterCalled + ", preDeregisterCalled = "
+ + preDeregisterCalled + ", postDeregisterCalled = "
+ + postDeregisterCalled);
+ }
+ static class Wrapped implements MBeanRegistration,Serializable {
+
+ public ObjectName preRegister(MBeanServer server, ObjectName name)
+ throws Exception {
+ preRegisterCalled = true;
+ return name;
+ }
+
+ public void postRegister(Boolean registrationDone) {
+ postRegisterCalled = true;
+ }
+
+ public void preDeregister() throws Exception {
+ preDeregisterCalled = true;
+ }
+
+ public void postDeregister() {
+ postDeregisterCalled = true;
+ }
+
+ }
+
+ public static void main(String[] args) throws Exception {
+ StandardMBean std = new StandardMBean(new Wrapped(),
+ Serializable.class);
+ ObjectName name = ObjectName.valueOf(":type=Test");
+ ManagementFactory.getPlatformMBeanServer().registerMBean(std,name);
+ ManagementFactory.getPlatformMBeanServer().unregisterMBean(name);
+ checkResult(false);
+ StandardMBean.Options opt = new StandardMBean.Options();
+ opt.setMBeanRegistrationForwarded(true);
+ std = new StandardMBean(new Wrapped(),
+ Serializable.class, opt );
+ ManagementFactory.getPlatformMBeanServer().registerMBean(std,name);
+ ManagementFactory.getPlatformMBeanServer().unregisterMBean(name);
+ checkResult(true);
+ System.out.println("Test OK");
+ }
+}