8007467: Better JMX type conversion

Reviewed-by: dfuchs, mchung, skoivu
This commit is contained in:
Shanliang Jiang 2013-04-02 10:38:51 +02:00
parent 7d8a89c6c1
commit 30245ce543
5 changed files with 26 additions and 7 deletions

View File

@ -33,6 +33,7 @@ import javax.management.Descriptor;
import javax.management.MBeanException; import javax.management.MBeanException;
import javax.management.openmbean.OpenDataException; import javax.management.openmbean.OpenDataException;
import javax.management.openmbean.OpenType; import javax.management.openmbean.OpenType;
import sun.reflect.misc.MethodUtil;
final class ConvertingMethod { final class ConvertingMethod {
static ConvertingMethod from(Method m) { static ConvertingMethod from(Method m) {
@ -189,7 +190,7 @@ final class ConvertingMethod {
"from open values: " + e; "from open values: " + e;
throw new MBeanException(e, msg); throw new MBeanException(e, msg);
} }
final Object javaReturn = method.invoke(obj, javaParams); final Object javaReturn = MethodUtil.invoke(method, obj, javaParams);
try { try {
return returnMapping.toOpenValue(javaReturn); return returnMapping.toOpenValue(javaReturn);
} catch (OpenDataException e) { } catch (OpenDataException e) {

View File

@ -74,6 +74,8 @@ import javax.management.openmbean.SimpleType;
import javax.management.openmbean.TabularData; import javax.management.openmbean.TabularData;
import javax.management.openmbean.TabularDataSupport; import javax.management.openmbean.TabularDataSupport;
import javax.management.openmbean.TabularType; 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 * <p>A converter between Java types and the limited set of classes
@ -299,6 +301,7 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
private static <T extends Enum<T>> MXBeanMapping private static <T extends Enum<T>> MXBeanMapping
makeEnumMapping(Class<?> enumClass, Class<T> fake) { makeEnumMapping(Class<?> enumClass, Class<T> fake) {
ReflectUtil.checkPackageAccess(enumClass);
return new EnumMapping<T>(Util.<Class<T>>cast(enumClass)); return new EnumMapping<T>(Util.<Class<T>>cast(enumClass));
} }
@ -423,6 +426,7 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
(c.getName().equals("com.sun.management.GcInfo") && (c.getName().equals("com.sun.management.GcInfo") &&
c.getClassLoader() == null); c.getClassLoader() == null);
ReflectUtil.checkPackageAccess(c);
final List<Method> methods = final List<Method> methods =
MBeanAnalyzer.eliminateCovariantMethods(Arrays.asList(c.getMethods())); MBeanAnalyzer.eliminateCovariantMethods(Arrays.asList(c.getMethods()));
final SortedMap<String,Method> getterMap = newSortedMap(); final SortedMap<String,Method> getterMap = newSortedMap();
@ -828,7 +832,7 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
Object[] values = new Object[getters.length]; Object[] values = new Object[getters.length];
for (int i = 0; i < getters.length; i++) { for (int i = 0; i < getters.length; i++) {
try { try {
Object got = getters[i].invoke(value, (Object[]) null); Object got = MethodUtil.invoke(getters[i], value, (Object[]) null);
values[i] = getterMappings[i].toOpenValue(got); values[i] = getterMappings[i].toOpenValue(got);
} catch (Exception e) { } catch (Exception e) {
throw openDataException("Error calling getter for " + throw openDataException("Error calling getter for " +
@ -1011,7 +1015,7 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
MXBeanMapping[] converters) MXBeanMapping[] converters)
throws InvalidObjectException { throws InvalidObjectException {
try { try {
return fromMethod.invoke(null, cd); return MethodUtil.invoke(fromMethod, null, new Object[] {cd});
} catch (Exception e) { } catch (Exception e) {
final String msg = "Failed to invoke from(CompositeData)"; final String msg = "Failed to invoke from(CompositeData)";
throw invalidObjectException(msg, e); throw invalidObjectException(msg, e);
@ -1107,13 +1111,15 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
throws InvalidObjectException { throws InvalidObjectException {
Object o; Object o;
try { try {
o = getTargetClass().newInstance(); final Class<?> targetClass = getTargetClass();
ReflectUtil.checkPackageAccess(targetClass);
o = targetClass.newInstance();
for (int i = 0; i < itemNames.length; i++) { for (int i = 0; i < itemNames.length; i++) {
if (cd.containsKey(itemNames[i])) { if (cd.containsKey(itemNames[i])) {
Object openItem = cd.get(itemNames[i]); Object openItem = cd.get(itemNames[i]);
Object javaItem = Object javaItem =
converters[i].fromOpenValue(openItem); converters[i].fromOpenValue(openItem);
setters[i].invoke(o, javaItem); MethodUtil.invoke(setters[i], o, new Object[] {javaItem});
} }
} }
} catch (Exception e) { } catch (Exception e) {
@ -1363,6 +1369,7 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
} }
try { try {
ReflectUtil.checkPackageAccess(max.constructor.getDeclaringClass());
return max.constructor.newInstance(params); return max.constructor.newInstance(params);
} catch (Exception e) { } catch (Exception e) {
final String msg = final String msg =

View File

@ -38,6 +38,7 @@ import javax.management.MBeanOperationInfo;
import javax.management.NotCompliantMBeanException; import javax.management.NotCompliantMBeanException;
import javax.management.NotificationBroadcaster; import javax.management.NotificationBroadcaster;
import javax.management.NotificationBroadcasterSupport; import javax.management.NotificationBroadcasterSupport;
import sun.reflect.misc.MethodUtil;
/** /**
* @since 1.6 * @since 1.6
@ -108,7 +109,7 @@ class StandardMBeanIntrospector extends MBeanIntrospector<Method> {
Object invokeM2(Method m, Object target, Object[] args, Object cookie) Object invokeM2(Method m, Object target, Object[] args, Object cookie)
throws InvocationTargetException, IllegalAccessException, throws InvocationTargetException, IllegalAccessException,
MBeanException { MBeanException {
return m.invoke(target, args); return MethodUtil.invoke(m, target, args);
} }
@Override @Override

View File

@ -169,6 +169,8 @@ public class CompositeDataInvocationHandler implements InvocationHandler {
the only non-final methods in Object that are not the only non-final methods in Object that are not
handled above are finalize and clone, and these handled above are finalize and clone, and these
are not overridden in generated proxies. */ 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); return method.invoke(this, args);
} }
} }

View File

@ -45,6 +45,9 @@ import javax.management.DescriptorRead;
import javax.management.ImmutableDescriptor; import javax.management.ImmutableDescriptor;
import javax.management.MBeanAttributeInfo; import javax.management.MBeanAttributeInfo;
import com.sun.jmx.remote.util.EnvHelp; 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. * Describes an attribute of an open MBean.
@ -690,6 +693,7 @@ public class OpenMBeanAttributeInfoSupport
private static <T> T convertFromString(String s, OpenType<T> openType) { private static <T> T convertFromString(String s, OpenType<T> openType) {
Class<T> c; Class<T> c;
try { try {
ReflectUtil.checkPackageAccess(openType.safeGetClassName());
c = cast(Class.forName(openType.safeGetClassName())); c = cast(Class.forName(openType.safeGetClassName()));
} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) {
throw new NoClassDefFoundError(e.toString()); // can't happen throw new NoClassDefFoundError(e.toString()); // can't happen
@ -698,6 +702,8 @@ public class OpenMBeanAttributeInfoSupport
// Look for: public static T valueOf(String) // Look for: public static T valueOf(String)
Method valueOf; Method valueOf;
try { 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); valueOf = c.getMethod("valueOf", String.class);
if (!Modifier.isStatic(valueOf.getModifiers()) || if (!Modifier.isStatic(valueOf.getModifiers()) ||
valueOf.getReturnType() != c) valueOf.getReturnType() != c)
@ -707,7 +713,7 @@ public class OpenMBeanAttributeInfoSupport
} }
if (valueOf != null) { if (valueOf != null) {
try { try {
return c.cast(valueOf.invoke(null, s)); return c.cast(MethodUtil.invoke(valueOf, null, new Object[] {s}));
} catch (Exception e) { } catch (Exception e) {
final String msg = final String msg =
"Could not convert \"" + s + "\" using method: " + valueOf; "Could not convert \"" + s + "\" using method: " + valueOf;
@ -718,6 +724,8 @@ public class OpenMBeanAttributeInfoSupport
// Look for: public T(String) // Look for: public T(String)
Constructor<T> con; Constructor<T> con;
try { 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); con = c.getConstructor(String.class);
} catch (NoSuchMethodException e) { } catch (NoSuchMethodException e) {
con = null; con = null;