jdk/src/share/classes/java/lang/Class.java

Print this page
rev 5671 : 7197546: (proxy) Reflect about creating reflective proxies
Reviewed-by: alanb, jdn, jrose

@@ -63,11 +63,13 @@
 import sun.reflect.generics.repository.MethodRepository;
 import sun.reflect.generics.repository.ConstructorRepository;
 import sun.reflect.generics.scope.ClassScope;
 import sun.security.util.SecurityConstants;
 import java.lang.annotation.Annotation;
+import java.lang.reflect.Proxy;
 import sun.reflect.annotation.*;
+import sun.reflect.misc.ReflectUtil;
 
 /**
  * Instances of the class {@code Class} represent classes and
  * interfaces in a running Java application.  An enum is a kind of
  * class and an annotation is a kind of interface.  Every array also

@@ -318,11 +320,11 @@
      */
     public T newInstance()
         throws InstantiationException, IllegalAccessException
     {
         if (System.getSecurityManager() != null) {
-            checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+            checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), false);
         }
         return newInstance0();
     }
 
     private T newInstance0()

@@ -1295,11 +1297,11 @@
      */
     public Class<?>[] getClasses() {
         // be very careful not to change the stack depth of this
         // checkMemberAccess call for security reasons
         // see java.lang.SecurityManager.checkMemberAccess
-        checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+        checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), false);
 
         // Privileged so this implementation can look at DECLARED classes,
         // something the caller might not have privilege to do.  The code here
         // is allowed to look at DECLARED classes because (1) it does not hand
         // out anything other than public members and (2) public member access

@@ -1370,11 +1372,11 @@
      */
     public Field[] getFields() throws SecurityException {
         // be very careful not to change the stack depth of this
         // checkMemberAccess call for security reasons
         // see java.lang.SecurityManager.checkMemberAccess
-        checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+        checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
         return copyFields(privateGetPublicFields(null));
     }
 
 
     /**

@@ -1421,11 +1423,11 @@
      */
     public Method[] getMethods() throws SecurityException {
         // be very careful not to change the stack depth of this
         // checkMemberAccess call for security reasons
         // see java.lang.SecurityManager.checkMemberAccess
-        checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+        checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
         return copyMethods(privateGetPublicMethods());
     }
 
 
     /**

@@ -1470,11 +1472,11 @@
      */
     public Constructor<?>[] getConstructors() throws SecurityException {
         // be very careful not to change the stack depth of this
         // checkMemberAccess call for security reasons
         // see java.lang.SecurityManager.checkMemberAccess
-        checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+        checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
         return copyConstructors(privateGetDeclaredConstructors(true));
     }
 
 
     /**

@@ -1529,11 +1531,11 @@
     public Field getField(String name)
         throws NoSuchFieldException, SecurityException {
         // be very careful not to change the stack depth of this
         // checkMemberAccess call for security reasons
         // see java.lang.SecurityManager.checkMemberAccess
-        checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+        checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
         Field field = getField0(name);
         if (field == null) {
             throw new NoSuchFieldException(name);
         }
         return field;

@@ -1614,11 +1616,11 @@
     public Method getMethod(String name, Class<?>... parameterTypes)
         throws NoSuchMethodException, SecurityException {
         // be very careful not to change the stack depth of this
         // checkMemberAccess call for security reasons
         // see java.lang.SecurityManager.checkMemberAccess
-        checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+        checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
         Method method = getMethod0(name, parameterTypes);
         if (method == null) {
             throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
         }
         return method;

@@ -1668,11 +1670,11 @@
     public Constructor<T> getConstructor(Class<?>... parameterTypes)
         throws NoSuchMethodException, SecurityException {
         // be very careful not to change the stack depth of this
         // checkMemberAccess call for security reasons
         // see java.lang.SecurityManager.checkMemberAccess
-        checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
+        checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
         return getConstructor0(parameterTypes, Member.PUBLIC);
     }
 
 
     /**

@@ -1710,11 +1712,11 @@
      */
     public Class<?>[] getDeclaredClasses() throws SecurityException {
         // be very careful not to change the stack depth of this
         // checkMemberAccess call for security reasons
         // see java.lang.SecurityManager.checkMemberAccess
-        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), false);
         return getDeclaredClasses0();
     }
 
 
     /**

@@ -1754,11 +1756,11 @@
      */
     public Field[] getDeclaredFields() throws SecurityException {
         // be very careful not to change the stack depth of this
         // checkMemberAccess call for security reasons
         // see java.lang.SecurityManager.checkMemberAccess
-        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
         return copyFields(privateGetDeclaredFields(false));
     }
 
 
     /**

@@ -1802,11 +1804,11 @@
      */
     public Method[] getDeclaredMethods() throws SecurityException {
         // be very careful not to change the stack depth of this
         // checkMemberAccess call for security reasons
         // see java.lang.SecurityManager.checkMemberAccess
-        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
         return copyMethods(privateGetDeclaredMethods(false));
     }
 
 
     /**

@@ -1847,11 +1849,11 @@
      */
     public Constructor<?>[] getDeclaredConstructors() throws SecurityException {
         // be very careful not to change the stack depth of this
         // checkMemberAccess call for security reasons
         // see java.lang.SecurityManager.checkMemberAccess
-        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
         return copyConstructors(privateGetDeclaredConstructors(false));
     }
 
 
     /**

@@ -1891,11 +1893,11 @@
     public Field getDeclaredField(String name)
         throws NoSuchFieldException, SecurityException {
         // be very careful not to change the stack depth of this
         // checkMemberAccess call for security reasons
         // see java.lang.SecurityManager.checkMemberAccess
-        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
         Field field = searchFields(privateGetDeclaredFields(false), name);
         if (field == null) {
             throw new NoSuchFieldException(name);
         }
         return field;

@@ -1946,11 +1948,11 @@
     public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
         throws NoSuchMethodException, SecurityException {
         // be very careful not to change the stack depth of this
         // checkMemberAccess call for security reasons
         // see java.lang.SecurityManager.checkMemberAccess
-        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
         Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes);
         if (method == null) {
             throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
         }
         return method;

@@ -1996,11 +1998,11 @@
     public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
         throws NoSuchMethodException, SecurityException {
         // be very careful not to change the stack depth of this
         // checkMemberAccess call for security reasons
         // see java.lang.SecurityManager.checkMemberAccess
-        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
+        checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
         return getConstructor0(parameterTypes, Member.DECLARED);
     }
 
     /**
      * Finds a resource with a given name.  The rules for searching resources

@@ -2166,24 +2168,31 @@
      * See java.lang.SecurityManager.checkMemberAccess.
      *
      * <p> Default policy: allow all clients access with normal Java access
      * control.
      */
-    private void checkMemberAccess(int which, ClassLoader ccl) {
+    private void checkMemberAccess(int which, ClassLoader ccl, boolean checkProxyInterfaces) {
         SecurityManager s = System.getSecurityManager();
         if (s != null) {
             s.checkMemberAccess(this, which);
             ClassLoader cl = getClassLoader0();
-            if ((ccl != null) && (ccl != cl) &&
-                  ((cl == null) || !cl.isAncestor(ccl))) {
+            if (ReflectUtil.needsPackageAccessCheck(ccl, cl)) {
                 String name = this.getName();
                 int i = name.lastIndexOf('.');
                 if (i != -1) {
-                    s.checkPackageAccess(name.substring(0, i));
+                    // skip the package access check on a proxy class in default proxy package
+                    String pkg = name.substring(0, i);
+                    if (!Proxy.isProxyClass(this) || !pkg.equals(ReflectUtil.PROXY_PACKAGE)) {
+                        s.checkPackageAccess(pkg);
                 }
             }
         }
+            // check package access on the proxy interfaces
+            if (checkProxyInterfaces && Proxy.isProxyClass(this)) {
+                ReflectUtil.checkProxyPackageAccess(ccl, this.getInterfaces());
+            }
+        }
     }
 
     /**
      * Add a package name prefix if the name is not absolute Remove leading "/"
      * if name is absolute