jdk/src/share/classes/java/lang/reflect/Proxy.java
changeset 16906 44dfee24cb71
parent 16108 e5fcdadc69b2
child 16923 50bfa0defec2
equal deleted inserted replaced
16905:0419f45c7761 16906:44dfee24cb71
    37 import java.util.Map;
    37 import java.util.Map;
    38 import java.util.Set;
    38 import java.util.Set;
    39 import java.util.List;
    39 import java.util.List;
    40 import java.util.WeakHashMap;
    40 import java.util.WeakHashMap;
    41 import sun.misc.ProxyGenerator;
    41 import sun.misc.ProxyGenerator;
       
    42 import sun.misc.VM;
       
    43 import sun.reflect.CallerSensitive;
    42 import sun.reflect.Reflection;
    44 import sun.reflect.Reflection;
    43 import sun.reflect.misc.ReflectUtil;
    45 import sun.reflect.misc.ReflectUtil;
    44 import sun.security.util.SecurityConstants;
    46 import sun.security.util.SecurityConstants;
    45 
    47 
    46 /**
    48 /**
   406      *          parameters that may be passed to {@code getProxyClass}
   408      *          parameters that may be passed to {@code getProxyClass}
   407      *          are violated
   409      *          are violated
   408      * @throws  NullPointerException if the {@code interfaces} array
   410      * @throws  NullPointerException if the {@code interfaces} array
   409      *          argument or any of its elements are {@code null}
   411      *          argument or any of its elements are {@code null}
   410      */
   412      */
       
   413     @CallerSensitive
   411     public static Class<?> getProxyClass(ClassLoader loader,
   414     public static Class<?> getProxyClass(ClassLoader loader,
   412                                          Class<?>... interfaces)
   415                                          Class<?>... interfaces)
   413         throws IllegalArgumentException
   416         throws IllegalArgumentException
   414     {
   417     {
   415         return getProxyClass0(loader, interfaces); // stack walk magic: do not refactor
       
   416     }
       
   417 
       
   418     private static void checkProxyLoader(ClassLoader ccl,
       
   419                                          ClassLoader loader)
       
   420     {
       
   421         SecurityManager sm = System.getSecurityManager();
   418         SecurityManager sm = System.getSecurityManager();
   422         if (sm != null) {
   419         if (sm != null) {
   423             if (loader == null && ccl != null) {
   420             checkProxyAccess(Reflection.getCallerClass(), loader, interfaces);
   424                 if (!ProxyAccessHelper.allowNullLoader) {
   421         }
   425                     sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
   422 
   426                 }
   423         return getProxyClass0(loader, interfaces);
   427             }
       
   428         }
       
   429     }
   424     }
   430 
   425 
   431     /*
   426     /*
   432      * Generate a proxy class (caller-sensitive).
   427      * Check permissions required to create a Proxy class.
   433      *
   428      *
   434      * To define a proxy class, it performs the access checks as in
   429      * To define a proxy class, it performs the access checks as in
   435      * Class.forName (VM will invoke ClassLoader.checkPackageAccess):
   430      * Class.forName (VM will invoke ClassLoader.checkPackageAccess):
   436      * 1. "getClassLoader" permission check if loader == null
   431      * 1. "getClassLoader" permission check if loader == null
   437      * 2. checkPackageAccess on the interfaces it implements
   432      * 2. checkPackageAccess on the interfaces it implements
   444      * the defining loader of the interface.  If the caller's class loader
   439      * the defining loader of the interface.  If the caller's class loader
   445      * is not the same as the defining loader of the interface, the VM
   440      * is not the same as the defining loader of the interface, the VM
   446      * will throw IllegalAccessError when the generated proxy class is
   441      * will throw IllegalAccessError when the generated proxy class is
   447      * being defined via the defineClass0 method.
   442      * being defined via the defineClass0 method.
   448      */
   443      */
       
   444     private static void checkProxyAccess(Class<?> caller,
       
   445                                          ClassLoader loader,
       
   446                                          Class<?>... interfaces)
       
   447     {
       
   448         SecurityManager sm = System.getSecurityManager();
       
   449         if (sm != null) {
       
   450             ClassLoader ccl = caller.getClassLoader();
       
   451             if (VM.isSystemDomainLoader(loader) && !VM.isSystemDomainLoader(ccl)) {
       
   452                 if (!ProxyAccessHelper.allowNullLoader) {
       
   453                     sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
       
   454                 }
       
   455             }
       
   456             ReflectUtil.checkProxyPackageAccess(ccl, interfaces);
       
   457         }
       
   458     }
       
   459 
       
   460     /**
       
   461      * Generate a proxy class.  Must call the checkProxyAccess method
       
   462      * to perform permission checks before calling this.
       
   463      */
   449     private static Class<?> getProxyClass0(ClassLoader loader,
   464     private static Class<?> getProxyClass0(ClassLoader loader,
   450                                            Class<?>... interfaces) {
   465                                            Class<?>... interfaces) {
   451         SecurityManager sm = System.getSecurityManager();
       
   452         if (sm != null) {
       
   453             final int CALLER_FRAME = 3; // 0: Reflection, 1: getProxyClass0 2: Proxy 3: caller
       
   454             final Class<?> caller = Reflection.getCallerClass(CALLER_FRAME);
       
   455             final ClassLoader ccl = caller.getClassLoader();
       
   456             checkProxyLoader(ccl, loader);
       
   457             ReflectUtil.checkProxyPackageAccess(ccl, interfaces);
       
   458         }
       
   459 
       
   460         if (interfaces.length > 65535) {
   466         if (interfaces.length > 65535) {
   461             throw new IllegalArgumentException("interface limit exceeded");
   467             throw new IllegalArgumentException("interface limit exceeded");
   462         }
   468         }
   463 
   469 
   464         Class<?> proxyClass = null;
   470         Class<?> proxyClass = null;
   696      * @throws  NullPointerException if the {@code interfaces} array
   702      * @throws  NullPointerException if the {@code interfaces} array
   697      *          argument or any of its elements are {@code null}, or
   703      *          argument or any of its elements are {@code null}, or
   698      *          if the invocation handler, {@code h}, is
   704      *          if the invocation handler, {@code h}, is
   699      *          {@code null}
   705      *          {@code null}
   700      */
   706      */
       
   707     @CallerSensitive
   701     public static Object newProxyInstance(ClassLoader loader,
   708     public static Object newProxyInstance(ClassLoader loader,
   702                                           Class<?>[] interfaces,
   709                                           Class<?>[] interfaces,
   703                                           InvocationHandler h)
   710                                           InvocationHandler h)
   704         throws IllegalArgumentException
   711         throws IllegalArgumentException
   705     {
   712     {
   706         if (h == null) {
   713         if (h == null) {
   707             throw new NullPointerException();
   714             throw new NullPointerException();
   708         }
   715         }
   709 
   716 
       
   717         final SecurityManager sm = System.getSecurityManager();
       
   718         if (sm != null) {
       
   719             checkProxyAccess(Reflection.getCallerClass(), loader, interfaces);
       
   720         }
       
   721 
   710         /*
   722         /*
   711          * Look up or generate the designated proxy class.
   723          * Look up or generate the designated proxy class.
   712          */
   724          */
   713         Class<?> cl = getProxyClass0(loader, interfaces); // stack walk magic: do not refactor
   725         Class<?> cl = getProxyClass0(loader, interfaces);
   714 
   726 
   715         /*
   727         /*
   716          * Invoke its constructor with the designated invocation handler.
   728          * Invoke its constructor with the designated invocation handler.
   717          */
   729          */
   718         try {
   730         try {
   719             final Constructor<?> cons = cl.getConstructor(constructorParams);
   731             final Constructor<?> cons = cl.getConstructor(constructorParams);
   720             final InvocationHandler ih = h;
   732             final InvocationHandler ih = h;
   721             SecurityManager sm = System.getSecurityManager();
       
   722             if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(cl)) {
   733             if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(cl)) {
   723                 // create proxy instance with doPrivilege as the proxy class may
   734                 // create proxy instance with doPrivilege as the proxy class may
   724                 // implement non-public interfaces that requires a special permission
   735                 // implement non-public interfaces that requires a special permission
   725                 return AccessController.doPrivileged(new PrivilegedAction<Object>() {
   736                 return AccessController.doPrivileged(new PrivilegedAction<Object>() {
   726                     public Object run() {
   737                     public Object run() {