< prev index next >

src/java.base/share/classes/java/lang/reflect/Proxy.java

Print this page




  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.lang.reflect;
  27 
  28 import java.lang.module.ModuleDescriptor;
  29 import java.security.AccessController;
  30 import java.security.PrivilegedAction;
  31 import java.util.Arrays;
  32 import java.util.Collections;
  33 import java.util.HashMap;
  34 import java.util.HashSet;
  35 import java.util.IdentityHashMap;
  36 import java.util.List;
  37 import java.util.Map;
  38 import java.util.Objects;
  39 import java.util.Set;
  40 import java.util.concurrent.atomic.AtomicInteger;
  41 import java.util.concurrent.atomic.AtomicLong;
  42 import java.util.stream.Collectors;
  43 import java.util.stream.Stream;
  44 
  45 import jdk.internal.loader.BootLoader;


  46 import jdk.internal.module.Modules;
  47 import jdk.internal.misc.Unsafe;
  48 import jdk.internal.misc.VM;
  49 import jdk.internal.reflect.CallerSensitive;
  50 import jdk.internal.reflect.Reflection;
  51 import jdk.internal.loader.ClassLoaderValue;
  52 import sun.reflect.misc.ReflectUtil;
  53 import sun.security.action.GetPropertyAction;
  54 import sun.security.util.SecurityConstants;
  55 
  56 import static java.lang.module.ModuleDescriptor.Modifier.SYNTHETIC;
  57 
  58 
  59 /**
  60  *
  61  * {@code Proxy} provides static methods for creating objects that act like instances
  62  * of interfaces but allow for customized method invocation.
  63  * To create a proxy instance for some interface {@code Foo}:
  64  * <pre>{@code
  65  *     InvocationHandler handler = new MyInvocationHandler(...);
  66  *     Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
  67  *                                          new Class<?>[] { Foo.class },


 451                                          Class<?> ... interfaces)
 452     {
 453         SecurityManager sm = System.getSecurityManager();
 454         if (sm != null) {
 455             ClassLoader ccl = caller.getClassLoader();
 456             if (loader == null && ccl != null) {
 457                 sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
 458             }
 459             ReflectUtil.checkProxyPackageAccess(ccl, interfaces);
 460         }
 461     }
 462 
 463     /**
 464      * Builder for a proxy class.
 465      *
 466      * If the module is not specified in this ProxyBuilder constructor,
 467      * it will map from the given loader and interfaces to the module
 468      * in which the proxy class will be defined.
 469      */
 470     private static final class ProxyBuilder {
 471         private static final Unsafe UNSAFE = Unsafe.getUnsafe();
 472 
 473         // prefix for all proxy class names
 474         private static final String proxyClassNamePrefix = "$Proxy";
 475 
 476         // next number to use for generation of unique proxy class names
 477         private static final AtomicLong nextUniqueNumber = new AtomicLong();
 478 
 479         // a reverse cache of defined proxy classes
 480         private static final ClassLoaderValue<Boolean> reverseProxyCache =
 481             new ClassLoaderValue<>();
 482 
 483         private static Class<?> defineProxyClass(Module m, List<Class<?>> interfaces) {
 484             String proxyPkg = null;     // package to define proxy class in
 485             int accessFlags = Modifier.PUBLIC | Modifier.FINAL;
 486 
 487             /*
 488              * Record the package of a non-public proxy interface so that the
 489              * proxy class will be defined in the same package.  Verify that
 490              * all non-public proxy interfaces are in the same package.
 491              */


 518                 }
 519             }
 520 
 521             /*
 522              * Choose a name for the proxy class to generate.
 523              */
 524             long num = nextUniqueNumber.getAndIncrement();
 525             String proxyName = proxyPkg.isEmpty()
 526                                     ? proxyClassNamePrefix + num
 527                                     : proxyPkg + "." + proxyClassNamePrefix + num;
 528 
 529             ClassLoader loader = getLoader(m);
 530             trace(proxyName, m, loader, interfaces);
 531 
 532             /*
 533              * Generate the specified proxy class.
 534              */
 535             byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
 536                     proxyName, interfaces.toArray(EMPTY_CLASS_ARRAY), accessFlags);
 537             try {
 538                 Class<?> pc = UNSAFE.defineClass(proxyName, proxyClassFile,
 539                                                  0, proxyClassFile.length,
 540                                                  loader, null);
 541                 reverseProxyCache.sub(pc).putIfAbsent(loader, Boolean.TRUE);
 542                 return pc;
 543             } catch (ClassFormatError e) {
 544                 /*
 545                  * A ClassFormatError here means that (barring bugs in the
 546                  * proxy class generation code) there was some other
 547                  * invalid aspect of the arguments supplied to the proxy
 548                  * class creation (such as virtual machine limitations
 549                  * exceeded).
 550                  */
 551                 throw new IllegalArgumentException(e.toString());
 552             }
 553         }
 554 
 555         /**
 556          * Test if given class is a class defined by
 557          * {@link #defineProxyClass(Module, List)}
 558          */
 559         static boolean isProxyClass(Class<?> c) {
 560             return Objects.equals(reverseProxyCache.sub(c).get(c.getClassLoader()),




  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.lang.reflect;
  27 
  28 import java.lang.module.ModuleDescriptor;
  29 import java.security.AccessController;
  30 import java.security.PrivilegedAction;
  31 import java.util.Arrays;
  32 import java.util.Collections;
  33 import java.util.HashMap;
  34 import java.util.HashSet;
  35 import java.util.IdentityHashMap;
  36 import java.util.List;
  37 import java.util.Map;
  38 import java.util.Objects;
  39 import java.util.Set;
  40 import java.util.concurrent.atomic.AtomicInteger;
  41 import java.util.concurrent.atomic.AtomicLong;


  42 
  43 import jdk.internal.loader.BootLoader;
  44 import jdk.internal.misc.JavaLangAccess;
  45 import jdk.internal.misc.SharedSecrets;
  46 import jdk.internal.module.Modules;

  47 import jdk.internal.misc.VM;
  48 import jdk.internal.reflect.CallerSensitive;
  49 import jdk.internal.reflect.Reflection;
  50 import jdk.internal.loader.ClassLoaderValue;
  51 import sun.reflect.misc.ReflectUtil;
  52 import sun.security.action.GetPropertyAction;
  53 import sun.security.util.SecurityConstants;
  54 
  55 import static java.lang.module.ModuleDescriptor.Modifier.SYNTHETIC;
  56 
  57 
  58 /**
  59  *
  60  * {@code Proxy} provides static methods for creating objects that act like instances
  61  * of interfaces but allow for customized method invocation.
  62  * To create a proxy instance for some interface {@code Foo}:
  63  * <pre>{@code
  64  *     InvocationHandler handler = new MyInvocationHandler(...);
  65  *     Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
  66  *                                          new Class<?>[] { Foo.class },


 450                                          Class<?> ... interfaces)
 451     {
 452         SecurityManager sm = System.getSecurityManager();
 453         if (sm != null) {
 454             ClassLoader ccl = caller.getClassLoader();
 455             if (loader == null && ccl != null) {
 456                 sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
 457             }
 458             ReflectUtil.checkProxyPackageAccess(ccl, interfaces);
 459         }
 460     }
 461 
 462     /**
 463      * Builder for a proxy class.
 464      *
 465      * If the module is not specified in this ProxyBuilder constructor,
 466      * it will map from the given loader and interfaces to the module
 467      * in which the proxy class will be defined.
 468      */
 469     private static final class ProxyBuilder {
 470         private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
 471 
 472         // prefix for all proxy class names
 473         private static final String proxyClassNamePrefix = "$Proxy";
 474 
 475         // next number to use for generation of unique proxy class names
 476         private static final AtomicLong nextUniqueNumber = new AtomicLong();
 477 
 478         // a reverse cache of defined proxy classes
 479         private static final ClassLoaderValue<Boolean> reverseProxyCache =
 480             new ClassLoaderValue<>();
 481 
 482         private static Class<?> defineProxyClass(Module m, List<Class<?>> interfaces) {
 483             String proxyPkg = null;     // package to define proxy class in
 484             int accessFlags = Modifier.PUBLIC | Modifier.FINAL;
 485 
 486             /*
 487              * Record the package of a non-public proxy interface so that the
 488              * proxy class will be defined in the same package.  Verify that
 489              * all non-public proxy interfaces are in the same package.
 490              */


 517                 }
 518             }
 519 
 520             /*
 521              * Choose a name for the proxy class to generate.
 522              */
 523             long num = nextUniqueNumber.getAndIncrement();
 524             String proxyName = proxyPkg.isEmpty()
 525                                     ? proxyClassNamePrefix + num
 526                                     : proxyPkg + "." + proxyClassNamePrefix + num;
 527 
 528             ClassLoader loader = getLoader(m);
 529             trace(proxyName, m, loader, interfaces);
 530 
 531             /*
 532              * Generate the specified proxy class.
 533              */
 534             byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
 535                     proxyName, interfaces.toArray(EMPTY_CLASS_ARRAY), accessFlags);
 536             try {
 537                 Class<?> pc = JLA.defineClass(loader, proxyName, proxyClassFile,
 538                                               null, "__dynamic_proxy__");

 539                 reverseProxyCache.sub(pc).putIfAbsent(loader, Boolean.TRUE);
 540                 return pc;
 541             } catch (ClassFormatError e) {
 542                 /*
 543                  * A ClassFormatError here means that (barring bugs in the
 544                  * proxy class generation code) there was some other
 545                  * invalid aspect of the arguments supplied to the proxy
 546                  * class creation (such as virtual machine limitations
 547                  * exceeded).
 548                  */
 549                 throw new IllegalArgumentException(e.toString());
 550             }
 551         }
 552 
 553         /**
 554          * Test if given class is a class defined by
 555          * {@link #defineProxyClass(Module, List)}
 556          */
 557         static boolean isProxyClass(Class<?> c) {
 558             return Objects.equals(reverseProxyCache.sub(c).get(c.getClassLoader()),


< prev index next >