From 9f8bb22b73c3b374afbf1b3bc7df9cc8e6b9e108 Mon Sep 17 00:00:00 2001 From: Jaroslav Bachorik Date: Thu, 28 Mar 2013 09:39:26 +0100 Subject: [PATCH] 8008982: Adjust JMX for underlying interface changes Reviewed-by: mchung, dholmes, dfuchs, skoivu --- .../com/sun/jmx/mbeanserver/Introspector.java | 5 ++ .../share/classes/javax/management/JMX.java | 90 +++++++++++++------ .../MBeanServerInvocationHandler.java | 15 +--- 3 files changed, 71 insertions(+), 39 deletions(-) diff --git a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java index 7011920bf13..78117debaeb 100644 --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java @@ -228,6 +228,11 @@ public class Introspector { MXBeanIntrospector.getInstance().getAnalyzer(interfaceClass); } + public static void testComplianceMBeanInterface(Class interfaceClass) + throws NotCompliantMBeanException{ + StandardMBeanIntrospector.getInstance().getAnalyzer(interfaceClass); + } + /** * Basic method for testing if a given class is a JMX compliant * Standard MBean. This method is only called by the legacy code diff --git a/jdk/src/share/classes/javax/management/JMX.java b/jdk/src/share/classes/javax/management/JMX.java index 0b580d3a525..7f8cc411964 100644 --- a/jdk/src/share/classes/javax/management/JMX.java +++ b/jdk/src/share/classes/javax/management/JMX.java @@ -27,7 +27,9 @@ package javax.management; import com.sun.jmx.mbeanserver.Introspector; import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Modifier; import java.lang.reflect.Proxy; +import sun.reflect.misc.ReflectUtil; /** * Static methods from the JMX API. There are no instances of this class. @@ -203,11 +205,7 @@ public class JMX { ObjectName objectName, Class interfaceClass, boolean notificationEmitter) { - return MBeanServerInvocationHandler.newProxyInstance( - connection, - objectName, - interfaceClass, - notificationEmitter); + return createProxy(connection, objectName, interfaceClass, notificationEmitter, false); } /** @@ -345,26 +343,7 @@ public class JMX { ObjectName objectName, Class interfaceClass, boolean notificationEmitter) { - // Check interface for MXBean compliance - // - try { - Introspector.testComplianceMXBeanInterface(interfaceClass); - } catch (NotCompliantMBeanException e) { - throw new IllegalArgumentException(e); - } - InvocationHandler handler = new MBeanServerInvocationHandler( - connection, objectName, true); - final Class[] interfaces; - if (notificationEmitter) { - interfaces = - new Class[] {interfaceClass, NotificationEmitter.class}; - } else - interfaces = new Class[] {interfaceClass}; - Object proxy = Proxy.newProxyInstance( - interfaceClass.getClassLoader(), - interfaces, - handler); - return interfaceClass.cast(proxy); + return createProxy(connection, objectName, interfaceClass, notificationEmitter, true); } /** @@ -392,4 +371,65 @@ public class JMX { // exactly the string "MXBean" since that would mean there // was no package name, which is pretty unlikely in practice. } + + /** + * Centralised M(X)Bean proxy creation code + * @param connection {@linkplain MBeanServerConnection} to use + * @param objectName M(X)Bean object name + * @param interfaceClass M(X)Bean interface class + * @param notificationEmitter Is a notification emitter? + * @param isMXBean Is an MXBean? + * @return Returns an M(X)Bean proxy generated for the provided interface class + * @throws SecurityException + * @throws IllegalArgumentException + */ + private static T createProxy(MBeanServerConnection connection, + ObjectName objectName, + Class interfaceClass, + boolean notificationEmitter, + boolean isMXBean) { + + if (System.getSecurityManager() != null) { + checkProxyInterface(interfaceClass); + } + try { + if (isMXBean) { + // Check interface for MXBean compliance + Introspector.testComplianceMXBeanInterface(interfaceClass); + } else { + // Check interface for MBean compliance + Introspector.testComplianceMBeanInterface(interfaceClass); + } + } catch (NotCompliantMBeanException e) { + throw new IllegalArgumentException(e); + } + + InvocationHandler handler = new MBeanServerInvocationHandler( + connection, objectName, isMXBean); + final Class[] interfaces; + if (notificationEmitter) { + interfaces = + new Class[] {interfaceClass, NotificationEmitter.class}; + } else + interfaces = new Class[] {interfaceClass}; + + Object proxy = Proxy.newProxyInstance( + interfaceClass.getClassLoader(), + interfaces, + handler); + return interfaceClass.cast(proxy); + } + + /** + * Checks for the M(X)Bean proxy interface being public and not restricted + * @param interfaceClass MBean proxy interface + * @throws SecurityException when the proxy interface comes from a restricted + * package or is not public + */ + private static void checkProxyInterface(Class interfaceClass) { + if (!Modifier.isPublic(interfaceClass.getModifiers())) { + throw new SecurityException("mbean proxy interface non-public"); + } + ReflectUtil.checkPackageAccess(interfaceClass); + } } diff --git a/jdk/src/share/classes/javax/management/MBeanServerInvocationHandler.java b/jdk/src/share/classes/javax/management/MBeanServerInvocationHandler.java index 41a969c7021..bc174fb303f 100644 --- a/jdk/src/share/classes/javax/management/MBeanServerInvocationHandler.java +++ b/jdk/src/share/classes/javax/management/MBeanServerInvocationHandler.java @@ -231,20 +231,7 @@ public class MBeanServerInvocationHandler implements InvocationHandler { ObjectName objectName, Class interfaceClass, boolean notificationBroadcaster) { - final InvocationHandler handler = - new MBeanServerInvocationHandler(connection, objectName); - final Class[] interfaces; - if (notificationBroadcaster) { - interfaces = - new Class[] {interfaceClass, NotificationEmitter.class}; - } else - interfaces = new Class[] {interfaceClass}; - - Object proxy = - Proxy.newProxyInstance(interfaceClass.getClassLoader(), - interfaces, - handler); - return interfaceClass.cast(proxy); + return JMX.newMBeanProxy(connection, objectName, interfaceClass, notificationBroadcaster); } public Object invoke(Object proxy, Method method, Object[] args)