8007467: Better JMX type conversion
authorsjiang
Tue, 02 Apr 2013 10:38:51 +0200
changeset 18220 1d724730bd2c
parent 18219 d4cd832b9802
child 18221 5cd0fa789013
8007467: Better JMX type conversion Reviewed-by: dfuchs, mchung, skoivu
jdk/src/share/classes/com/sun/jmx/mbeanserver/ConvertingMethod.java
jdk/src/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java
jdk/src/share/classes/com/sun/jmx/mbeanserver/StandardMBeanIntrospector.java
jdk/src/share/classes/javax/management/openmbean/CompositeDataInvocationHandler.java
jdk/src/share/classes/javax/management/openmbean/OpenMBeanAttributeInfoSupport.java
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/ConvertingMethod.java	Mon Apr 01 09:55:26 2013 -0700
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/ConvertingMethod.java	Tue Apr 02 10:38:51 2013 +0200
@@ -33,6 +33,7 @@
 import javax.management.MBeanException;
 import javax.management.openmbean.OpenDataException;
 import javax.management.openmbean.OpenType;
+import sun.reflect.misc.MethodUtil;
 
 final class ConvertingMethod {
     static ConvertingMethod from(Method m) {
@@ -189,7 +190,7 @@
                 "from open values: " + e;
             throw new MBeanException(e, msg);
         }
-        final Object javaReturn = method.invoke(obj, javaParams);
+        final Object javaReturn = MethodUtil.invoke(method, obj, javaParams);
         try {
             return returnMapping.toOpenValue(javaReturn);
         } catch (OpenDataException e) {
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java	Mon Apr 01 09:55:26 2013 -0700
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java	Tue Apr 02 10:38:51 2013 +0200
@@ -74,6 +74,8 @@
 import javax.management.openmbean.TabularData;
 import javax.management.openmbean.TabularDataSupport;
 import javax.management.openmbean.TabularType;
+import sun.reflect.misc.MethodUtil;
+import sun.reflect.misc.ReflectUtil;
 
 /**
  *   <p>A converter between Java types and the limited set of classes
@@ -299,6 +301,7 @@
 
     private static <T extends Enum<T>> MXBeanMapping
             makeEnumMapping(Class<?> enumClass, Class<T> fake) {
+        ReflectUtil.checkPackageAccess(enumClass);
         return new EnumMapping<T>(Util.<Class<T>>cast(enumClass));
     }
 
@@ -423,6 +426,7 @@
             (c.getName().equals("com.sun.management.GcInfo") &&
                 c.getClassLoader() == null);
 
+        ReflectUtil.checkPackageAccess(c);
         final List<Method> methods =
                 MBeanAnalyzer.eliminateCovariantMethods(Arrays.asList(c.getMethods()));
         final SortedMap<String,Method> getterMap = newSortedMap();
@@ -828,7 +832,7 @@
             Object[] values = new Object[getters.length];
             for (int i = 0; i < getters.length; i++) {
                 try {
-                    Object got = getters[i].invoke(value, (Object[]) null);
+                    Object got = MethodUtil.invoke(getters[i], value, (Object[]) null);
                     values[i] = getterMappings[i].toOpenValue(got);
                 } catch (Exception e) {
                     throw openDataException("Error calling getter for " +
@@ -1011,7 +1015,7 @@
                                        MXBeanMapping[] converters)
                 throws InvalidObjectException {
             try {
-                return fromMethod.invoke(null, cd);
+                return MethodUtil.invoke(fromMethod, null, new Object[] {cd});
             } catch (Exception e) {
                 final String msg = "Failed to invoke from(CompositeData)";
                 throw invalidObjectException(msg, e);
@@ -1107,13 +1111,15 @@
                 throws InvalidObjectException {
             Object o;
             try {
-                o = getTargetClass().newInstance();
+                final Class<?> targetClass = getTargetClass();
+                ReflectUtil.checkPackageAccess(targetClass);
+                o = targetClass.newInstance();
                 for (int i = 0; i < itemNames.length; i++) {
                     if (cd.containsKey(itemNames[i])) {
                         Object openItem = cd.get(itemNames[i]);
                         Object javaItem =
                             converters[i].fromOpenValue(openItem);
-                        setters[i].invoke(o, javaItem);
+                        MethodUtil.invoke(setters[i], o, new Object[] {javaItem});
                     }
                 }
             } catch (Exception e) {
@@ -1363,6 +1369,7 @@
             }
 
             try {
+                ReflectUtil.checkPackageAccess(max.constructor.getDeclaringClass());
                 return max.constructor.newInstance(params);
             } catch (Exception e) {
                 final String msg =
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/StandardMBeanIntrospector.java	Mon Apr 01 09:55:26 2013 -0700
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/StandardMBeanIntrospector.java	Tue Apr 02 10:38:51 2013 +0200
@@ -38,6 +38,7 @@
 import javax.management.NotCompliantMBeanException;
 import javax.management.NotificationBroadcaster;
 import javax.management.NotificationBroadcasterSupport;
+import sun.reflect.misc.MethodUtil;
 
 /**
  * @since 1.6
@@ -108,7 +109,7 @@
     Object invokeM2(Method m, Object target, Object[] args, Object cookie)
             throws InvocationTargetException, IllegalAccessException,
                    MBeanException {
-        return m.invoke(target, args);
+        return MethodUtil.invoke(m, target, args);
     }
 
     @Override
--- a/jdk/src/share/classes/javax/management/openmbean/CompositeDataInvocationHandler.java	Mon Apr 01 09:55:26 2013 -0700
+++ b/jdk/src/share/classes/javax/management/openmbean/CompositeDataInvocationHandler.java	Tue Apr 02 10:38:51 2013 +0200
@@ -169,6 +169,8 @@
                    the only non-final methods in Object that are not
                    handled above are finalize and clone, and these
                    are not overridden in generated proxies.  */
+                // this plain Method.invoke is called only if the declaring class
+                // is Object and so it's safe.
                 return method.invoke(this, args);
             }
         }
--- a/jdk/src/share/classes/javax/management/openmbean/OpenMBeanAttributeInfoSupport.java	Mon Apr 01 09:55:26 2013 -0700
+++ b/jdk/src/share/classes/javax/management/openmbean/OpenMBeanAttributeInfoSupport.java	Tue Apr 02 10:38:51 2013 +0200
@@ -45,6 +45,9 @@
 import javax.management.ImmutableDescriptor;
 import javax.management.MBeanAttributeInfo;
 import com.sun.jmx.remote.util.EnvHelp;
+import sun.reflect.misc.ConstructorUtil;
+import sun.reflect.misc.MethodUtil;
+import sun.reflect.misc.ReflectUtil;
 
 /**
  * Describes an attribute of an open MBean.
@@ -690,6 +693,7 @@
     private static <T> T convertFromString(String s, OpenType<T> openType) {
         Class<T> c;
         try {
+            ReflectUtil.checkPackageAccess(openType.safeGetClassName());
             c = cast(Class.forName(openType.safeGetClassName()));
         } catch (ClassNotFoundException e) {
             throw new NoClassDefFoundError(e.toString());  // can't happen
@@ -698,6 +702,8 @@
         // Look for: public static T valueOf(String)
         Method valueOf;
         try {
+            // It is safe to call this plain Class.getMethod because the class "c"
+            // was checked before by ReflectUtil.checkPackageAccess(openType.safeGetClassName());
             valueOf = c.getMethod("valueOf", String.class);
             if (!Modifier.isStatic(valueOf.getModifiers()) ||
                     valueOf.getReturnType() != c)
@@ -707,7 +713,7 @@
         }
         if (valueOf != null) {
             try {
-                return c.cast(valueOf.invoke(null, s));
+                return c.cast(MethodUtil.invoke(valueOf, null, new Object[] {s}));
             } catch (Exception e) {
                 final String msg =
                     "Could not convert \"" + s + "\" using method: " + valueOf;
@@ -718,6 +724,8 @@
         // Look for: public T(String)
         Constructor<T> con;
         try {
+            // It is safe to call this plain Class.getConstructor because the class "c"
+            // was checked before by ReflectUtil.checkPackageAccess(openType.safeGetClassName());
             con = c.getConstructor(String.class);
         } catch (NoSuchMethodException e) {
             con = null;