jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java
Print this page
rev 5696 : 8000537: Contextualize RequiredModelMBean class
Reviewed-by: ahgross, dsamersoff, skoivu
Contributed-by: Jaroslav Bachorik <jaroslav.bachorik@oracle.com>
*** 1,7 ****
/*
! * Copyright (c) 2000, 2008, Oracle and/or its affiliates. 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. Oracle designates this
--- 1,7 ----
/*
! * Copyright (c) 2000, 2012, Oracle and/or its affiliates. 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. Oracle designates this
*** 37,51 ****
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
- import java.util.Iterator;
import java.util.logging.Level;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
--- 37,53 ----
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+ import java.security.AccessControlContext;
+ import java.security.AccessController;
+ import java.security.PrivilegedAction;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.logging.Level;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
*** 76,85 ****
--- 78,89 ----
import javax.management.ReflectionException;
import javax.management.RuntimeErrorException;
import javax.management.RuntimeOperationsException;
import javax.management.ServiceNotFoundException;
import javax.management.loading.ClassLoaderRepository;
+ import sun.misc.JavaSecurityAccess;
+ import sun.misc.SharedSecrets;
import sun.reflect.misc.MethodUtil;
import sun.reflect.misc.ReflectUtil;
/**
*** 136,145 ****
--- 140,152 ----
/* records the registering in MBeanServer */
private boolean registered = false;
private transient MBeanServer server = null;
+ private final static JavaSecurityAccess javaSecurityAccess = SharedSecrets.getJavaSecurityAccess();
+ final private AccessControlContext acc = AccessController.getContext();
+
/*************************************/
/* constructors */
/*************************************/
/**
*** 1023,1037 ****
final Class<?> targetClass;
if (opClassName != null) {
try {
final ClassLoader targetClassLoader =
! targetObject.getClass().getClassLoader();
! targetClass = Class.forName(opClassName, false,
targetClassLoader);
} catch (ClassNotFoundException e) {
final String msg =
"class for invoke " + opName + " not found";
throw new ReflectionException(e, msg);
}
} else
--- 1030,1065 ----
final Class<?> targetClass;
if (opClassName != null) {
try {
+ AccessControlContext stack = AccessController.getContext();
+ final Object obj = targetObject;
+ final String className = opClassName;
+ final ClassNotFoundException[] caughtException = new ClassNotFoundException[1];
+
+ targetClass = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Class<?>>() {
+
+ @Override
+ public Class<?> run() {
+ try {
+ ReflectUtil.checkPackageAccess(className);
final ClassLoader targetClassLoader =
! obj.getClass().getClassLoader();
! return Class.forName(className, false,
targetClassLoader);
} catch (ClassNotFoundException e) {
+ caughtException[0] = e;
+ }
+ return null;
+ }
+ }, stack, acc);
+
+ if (caughtException[0] != null) {
+ throw caughtException[0];
+ }
+ } catch (ClassNotFoundException e) {
final String msg =
"class for invoke " + opName + " not found";
throw new ReflectionException(e, msg);
}
} else
*** 1059,1071 ****
cacheResult(opInfo, opDescr, result);
return result;
}
! private static Method resolveMethod(Class<?> targetClass,
String opMethodName,
! String[] sig)
throws ReflectionException {
final boolean tracing = MODELMBEAN_LOGGER.isLoggable(Level.FINER);
if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER,
--- 1087,1099 ----
cacheResult(opInfo, opDescr, result);
return result;
}
! private Method resolveMethod(Class<?> targetClass,
String opMethodName,
! final String[] sig)
throws ReflectionException {
final boolean tracing = MODELMBEAN_LOGGER.isLoggable(Level.FINER);
if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER,
*** 1076,1109 ****
final Class<?>[] argClasses;
if (sig == null)
argClasses = null;
else {
final ClassLoader targetClassLoader = targetClass.getClassLoader();
argClasses = new Class<?>[sig.length];
for (int i = 0; i < sig.length; i++) {
if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER,
RequiredModelMBean.class.getName(),"resolveMethod",
"resolve type " + sig[i]);
}
argClasses[i] = (Class<?>) primitiveClassMap.get(sig[i]);
if (argClasses[i] == null) {
try {
argClasses[i] =
Class.forName(sig[i], false, targetClassLoader);
} catch (ClassNotFoundException e) {
if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER,
RequiredModelMBean.class.getName(),
"resolveMethod",
"class not found");
}
final String msg = "Parameter class not found";
! throw new ReflectionException(e, msg);
}
}
}
}
try {
return targetClass.getMethod(opMethodName, argClasses);
--- 1104,1152 ----
final Class<?>[] argClasses;
if (sig == null)
argClasses = null;
else {
+ final AccessControlContext stack = AccessController.getContext();
+ final ReflectionException[] caughtException = new ReflectionException[1];
final ClassLoader targetClassLoader = targetClass.getClassLoader();
argClasses = new Class<?>[sig.length];
+
+ javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Void>() {
+
+ @Override
+ public Void run() {
for (int i = 0; i < sig.length; i++) {
if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER,
RequiredModelMBean.class.getName(),"resolveMethod",
"resolve type " + sig[i]);
}
argClasses[i] = (Class<?>) primitiveClassMap.get(sig[i]);
if (argClasses[i] == null) {
try {
+ ReflectUtil.checkPackageAccess(sig[i]);
argClasses[i] =
Class.forName(sig[i], false, targetClassLoader);
} catch (ClassNotFoundException e) {
if (tracing) {
MODELMBEAN_LOGGER.logp(Level.FINER,
RequiredModelMBean.class.getName(),
"resolveMethod",
"class not found");
}
final String msg = "Parameter class not found";
! caughtException[0] = new ReflectionException(e, msg);
! }
! }
}
+ return null;
}
+ }, stack, acc);
+
+ if (caughtException[0] != null) {
+ throw caughtException[0];
}
}
try {
return targetClass.getMethod(opMethodName, argClasses);
*** 1131,1141 ****
}
/* Find a method in RequiredModelMBean as determined by the given
parameters. Return null if there is none, or if the parameters
exclude using it. Called from invoke. */
! private static Method findRMMBMethod(String opMethodName,
Object targetObjectField,
String opClassName,
String[] sig) {
final boolean tracing = MODELMBEAN_LOGGER.isLoggable(Level.FINER);
--- 1174,1184 ----
}
/* Find a method in RequiredModelMBean as determined by the given
parameters. Return null if there is none, or if the parameters
exclude using it. Called from invoke. */
! private Method findRMMBMethod(String opMethodName,
Object targetObjectField,
String opClassName,
String[] sig) {
final boolean tracing = MODELMBEAN_LOGGER.isLoggable(Level.FINER);
*** 1153,1190 ****
final Class<RequiredModelMBean> rmmbClass = RequiredModelMBean.class;
final Class<?> targetClass;
if (opClassName == null)
targetClass = rmmbClass;
else {
try {
final ClassLoader targetClassLoader =
rmmbClass.getClassLoader();
! targetClass = Class.forName(opClassName, false,
targetClassLoader);
! if (!rmmbClass.isAssignableFrom(targetClass))
return null;
} catch (ClassNotFoundException e) {
return null;
}
}
try {
! return resolveMethod(targetClass, opMethodName, sig);
} catch (ReflectionException e) {
return null;
}
}
/*
* Invoke the given method, and throw the somewhat unpredictable
* appropriate exception if the method itself gets an exception.
*/
! private Object invokeMethod(String opName, Method method,
! Object targetObject, Object[] opArgs)
throws MBeanException, ReflectionException {
try {
ReflectUtil.checkPackageAccess(method.getDeclaringClass());
return MethodUtil.invoke(method, targetObject, opArgs);
} catch (RuntimeErrorException ree) {
throw new RuntimeOperationsException(ree,
"RuntimeException occurred in RequiredModelMBean "+
"while trying to invoke operation " + opName);
} catch (RuntimeException re) {
--- 1196,1266 ----
final Class<RequiredModelMBean> rmmbClass = RequiredModelMBean.class;
final Class<?> targetClass;
if (opClassName == null)
targetClass = rmmbClass;
else {
+ AccessControlContext stack = AccessController.getContext();
+ final String className = opClassName;
+ targetClass = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Class<?>>() {
+
+ @Override
+ public Class<?> run() {
try {
+ ReflectUtil.checkPackageAccess(className);
final ClassLoader targetClassLoader =
rmmbClass.getClassLoader();
! Class clz = Class.forName(className, false,
targetClassLoader);
! if (!rmmbClass.isAssignableFrom(clz))
return null;
+ return clz;
} catch (ClassNotFoundException e) {
return null;
}
}
+ }, stack, acc);
+ }
try {
! return targetClass != null ? resolveMethod(targetClass, opMethodName, sig) : null;
} catch (ReflectionException e) {
return null;
}
}
/*
* Invoke the given method, and throw the somewhat unpredictable
* appropriate exception if the method itself gets an exception.
*/
! private Object invokeMethod(String opName, final Method method,
! final Object targetObject, final Object[] opArgs)
throws MBeanException, ReflectionException {
try {
+ final Throwable[] caughtException = new Throwable[1];
+ AccessControlContext stack = AccessController.getContext();
+ Object rslt = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Object>() {
+
+ @Override
+ public Object run() {
+ try {
ReflectUtil.checkPackageAccess(method.getDeclaringClass());
return MethodUtil.invoke(method, targetObject, opArgs);
+ } catch (InvocationTargetException e) {
+ caughtException[0] = e;
+ } catch (IllegalAccessException e) {
+ caughtException[0] = e;
+ }
+ return null;
+ }
+ }, stack, acc);
+ if (caughtException[0] != null) {
+ if (caughtException[0] instanceof Exception) {
+ throw (Exception)caughtException[0];
+ } else if(caughtException[0] instanceof Error) {
+ throw (Error)caughtException[0];
+ }
+ }
+ return rslt;
} catch (RuntimeErrorException ree) {
throw new RuntimeOperationsException(ree,
"RuntimeException occurred in RequiredModelMBean "+
"while trying to invoke operation " + opName);
} catch (RuntimeException re) {
*** 1565,1575 ****
// !! cast response to right class
}
}
// make sure response class matches type field
! String respType = attrInfo.getType();
if (response != null) {
String responseClass = response.getClass().getName();
if (!respType.equals(responseClass)) {
boolean wrongType = false;
boolean primitiveType = false;
--- 1641,1651 ----
// !! cast response to right class
}
}
// make sure response class matches type field
! final String respType = attrInfo.getType();
if (response != null) {
String responseClass = response.getClass().getName();
if (!respType.equals(responseClass)) {
boolean wrongType = false;
boolean primitiveType = false;
*** 1588,1600 ****
wrongType = true;
} else {
// inequality may come from type subclassing
boolean subtype;
try {
ClassLoader cl =
! response.getClass().getClassLoader();
! Class<?> c = Class.forName(respType, true, cl);
subtype = c.isInstance(response);
} catch (Exception e) {
subtype = false;
if (tracing) {
--- 1664,1698 ----
wrongType = true;
} else {
// inequality may come from type subclassing
boolean subtype;
try {
+ final Class respClass = response.getClass();
+ final Exception[] caughException = new Exception[1];
+
+ AccessControlContext stack = AccessController.getContext();
+
+ Class c = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Class<?>>() {
+
+ @Override
+ public Class<?> run() {
+ try {
+ ReflectUtil.checkPackageAccess(respType);
ClassLoader cl =
! respClass.getClassLoader();
! return Class.forName(respType, true, cl);
! } catch (Exception e) {
! caughException[0] = e;
! }
! return null;
! }
! }, stack, acc);
!
! if (caughException[0] != null) {
! throw caughException[0];
! }
!
subtype = c.isInstance(response);
} catch (Exception e) {
subtype = false;
if (tracing) {
*** 2743,2762 ****
*/
protected ClassLoaderRepository getClassLoaderRepository() {
return MBeanServerFactory.getClassLoaderRepository(server);
}
! private Class<?> loadClass(String className)
throws ClassNotFoundException {
try {
return Class.forName(className);
} catch (ClassNotFoundException e) {
final ClassLoaderRepository clr =
getClassLoaderRepository();
if (clr == null) throw new ClassNotFoundException(className);
return clr.loadClass(className);
}
}
/*************************************/
/* MBeanRegistration Interface */
--- 2841,2881 ----
*/
protected ClassLoaderRepository getClassLoaderRepository() {
return MBeanServerFactory.getClassLoaderRepository(server);
}
! private Class<?> loadClass(final String className)
throws ClassNotFoundException {
+ AccessControlContext stack = AccessController.getContext();
+ final ClassNotFoundException[] caughtException = new ClassNotFoundException[1];
+
+ Class c = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Class<?>>() {
+
+ @Override
+ public Class<?> run() {
try {
+ ReflectUtil.checkPackageAccess(className);
return Class.forName(className);
} catch (ClassNotFoundException e) {
final ClassLoaderRepository clr =
getClassLoaderRepository();
+ try {
if (clr == null) throw new ClassNotFoundException(className);
return clr.loadClass(className);
+ } catch (ClassNotFoundException ex) {
+ caughtException[0] = ex;
+ }
}
+ return null;
+ }
+ }, stack, acc);
+
+ if (caughtException[0] != null) {
+ throw caughtException[0];
+ }
+
+ return c;
}
/*************************************/
/* MBeanRegistration Interface */