< prev index next >

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

Print this page

  33 import java.security.AccessController;
  34 import java.security.PrivilegedAction;
  35 import java.util.ArrayDeque;
  36 import java.util.Arrays;
  37 import java.util.Collections;
  38 import java.util.Deque;
  39 import java.util.HashMap;
  40 import java.util.HashSet;
  41 import java.util.IdentityHashMap;
  42 import java.util.List;
  43 import java.util.Map;
  44 import java.util.Objects;
  45 import java.util.Set;
  46 import java.util.concurrent.ConcurrentHashMap;
  47 import java.util.concurrent.atomic.AtomicInteger;
  48 import java.util.concurrent.atomic.AtomicLong;
  49 import java.util.function.BooleanSupplier;
  50 
  51 import jdk.internal.access.JavaLangAccess;
  52 import jdk.internal.access.SharedSecrets;

  53 import jdk.internal.module.Modules;
  54 import jdk.internal.misc.VM;
  55 import jdk.internal.reflect.CallerSensitive;
  56 import jdk.internal.reflect.Reflection;
  57 import jdk.internal.loader.ClassLoaderValue;
  58 import jdk.internal.vm.annotation.Stable;
  59 import sun.reflect.misc.ReflectUtil;
  60 import sun.security.action.GetPropertyAction;
  61 import sun.security.util.SecurityConstants;
  62 
  63 import static java.lang.invoke.MethodType.methodType;
  64 import static java.lang.module.ModuleDescriptor.Modifier.SYNTHETIC;
  65 
  66 /**
  67  *
  68  * {@code Proxy} provides static methods for creating objects that act like instances
  69  * of interfaces but allow for customized method invocation.
  70  * To create a proxy instance for some interface {@code Foo}:
  71  * <pre>{@code
  72  *     InvocationHandler handler = new MyInvocationHandler(...);

 503                         // This means a package-private superinterface exist in the unnamed
 504                         // package of a named module.
 505                         throw new InternalError("Unnamed package cannot be added to " + module);
 506                     }
 507 
 508                     if (!module.getDescriptor().packages().contains(packageName)) {
 509                         throw new InternalError(packageName + " not exist in " + module.getName());
 510                     }
 511 
 512                     if (!module.isOpen(packageName, Proxy.class.getModule())) {
 513                         // Required for default method invocation
 514                         throw new InternalError(packageName + " not open to " + Proxy.class.getModule());
 515                     }
 516                 } else {
 517                     if (Modifier.isPublic(accessFlags)) {
 518                         // All proxy superinterfaces are public, must be in named dynamic module
 519                         throw new InternalError("public proxy in unnamed module: " + module);
 520                     }
 521                 }
 522 
 523                 if ((accessFlags & ~Modifier.PUBLIC) != 0) {
 524                     throw new InternalError("proxy access flags must be Modifier.PUBLIC or 0");
 525                 }
 526             }
 527         }
 528 
 529         private static Class<?> defineProxyClass(ProxyClassContext context, List<Class<?>> interfaces) {
 530             /*
 531              * Choose a name for the proxy class to generate.
 532              */
 533             long num = nextUniqueNumber.getAndIncrement();
 534             String proxyName = context.packageName().isEmpty()
 535                                     ? proxyClassNamePrefix + num
 536                                     : context.packageName() + "." + proxyClassNamePrefix + num;
 537 
 538             ClassLoader loader = getLoader(context.module());
 539             trace(proxyName, context.module(), loader, interfaces);
 540 
 541             /*
 542              * Generate the specified proxy class.
 543              */
 544             byte[] proxyClassFile = ProxyGenerator.generateProxyClass(loader, proxyName, interfaces,
 545                                                                       context.accessFlags() | Modifier.FINAL);
 546             try {
 547                 Class<?> pc = JLA.defineClass(loader, proxyName, proxyClassFile,
 548                                               null, "__dynamic_proxy__");
 549                 reverseProxyCache.sub(pc).putIfAbsent(loader, Boolean.TRUE);
 550                 return pc;
 551             } catch (ClassFormatError e) {
 552                 /*
 553                  * A ClassFormatError here means that (barring bugs in the
 554                  * proxy class generation code) there was some other
 555                  * invalid aspect of the arguments supplied to the proxy
 556                  * class creation (such as virtual machine limitations
 557                  * exceeded).
 558                  */
 559                 throw new IllegalArgumentException(e.toString());
 560             }
 561         }
 562 
 563         /**
 564          * Test if given class is a class defined by
 565          * {@link #defineProxyClass(ProxyClassContext, List)}

 859             Module m = c.getModule();
 860             // add read edge and qualified export for the target module to access
 861             if (!target.canRead(m)) {
 862                 Modules.addReads(target, m);
 863             }
 864             String pn = c.getPackageName();
 865             if (!m.isExported(pn, target)) {
 866                 Modules.addExports(m, pn, target);
 867             }
 868         }
 869 
 870         /*
 871          * Ensure the given class is visible to the class loader.
 872          */
 873         private static void ensureVisible(ClassLoader ld, Class<?> c) {
 874             Class<?> type = null;
 875             try {
 876                 type = Class.forName(c.getName(), false, ld);
 877             } catch (ClassNotFoundException e) {
 878             }
 879             if (type != c) {
 880                 throw new IllegalArgumentException(c.getName() +
 881                         " referenced from a method is not visible from class loader");
 882             }
 883         }
 884 
 885         private static Class<?> getElementType(Class<?> type) {
 886             Class<?> e = type;
 887             while (e.isArray()) {
 888                 e = e.getComponentType();
 889             }
 890             return e;
 891         }
 892 
 893         private static final ClassLoaderValue<Module> dynProxyModules =
 894             new ClassLoaderValue<>();
 895         private static final AtomicInteger counter = new AtomicInteger();
 896 
 897         /*
 898          * Define a dynamic module with a package named $MODULE which
 899          * is unconditionally exported and another package named

  33 import java.security.AccessController;
  34 import java.security.PrivilegedAction;
  35 import java.util.ArrayDeque;
  36 import java.util.Arrays;
  37 import java.util.Collections;
  38 import java.util.Deque;
  39 import java.util.HashMap;
  40 import java.util.HashSet;
  41 import java.util.IdentityHashMap;
  42 import java.util.List;
  43 import java.util.Map;
  44 import java.util.Objects;
  45 import java.util.Set;
  46 import java.util.concurrent.ConcurrentHashMap;
  47 import java.util.concurrent.atomic.AtomicInteger;
  48 import java.util.concurrent.atomic.AtomicLong;
  49 import java.util.function.BooleanSupplier;
  50 
  51 import jdk.internal.access.JavaLangAccess;
  52 import jdk.internal.access.SharedSecrets;
  53 import jdk.internal.value.PrimitiveClass;
  54 import jdk.internal.module.Modules;
  55 import jdk.internal.misc.VM;
  56 import jdk.internal.reflect.CallerSensitive;
  57 import jdk.internal.reflect.Reflection;
  58 import jdk.internal.loader.ClassLoaderValue;
  59 import jdk.internal.vm.annotation.Stable;
  60 import sun.reflect.misc.ReflectUtil;
  61 import sun.security.action.GetPropertyAction;
  62 import sun.security.util.SecurityConstants;
  63 
  64 import static java.lang.invoke.MethodType.methodType;
  65 import static java.lang.module.ModuleDescriptor.Modifier.SYNTHETIC;
  66 
  67 /**
  68  *
  69  * {@code Proxy} provides static methods for creating objects that act like instances
  70  * of interfaces but allow for customized method invocation.
  71  * To create a proxy instance for some interface {@code Foo}:
  72  * <pre>{@code
  73  *     InvocationHandler handler = new MyInvocationHandler(...);

 504                         // This means a package-private superinterface exist in the unnamed
 505                         // package of a named module.
 506                         throw new InternalError("Unnamed package cannot be added to " + module);
 507                     }
 508 
 509                     if (!module.getDescriptor().packages().contains(packageName)) {
 510                         throw new InternalError(packageName + " not exist in " + module.getName());
 511                     }
 512 
 513                     if (!module.isOpen(packageName, Proxy.class.getModule())) {
 514                         // Required for default method invocation
 515                         throw new InternalError(packageName + " not open to " + Proxy.class.getModule());
 516                     }
 517                 } else {
 518                     if (Modifier.isPublic(accessFlags)) {
 519                         // All proxy superinterfaces are public, must be in named dynamic module
 520                         throw new InternalError("public proxy in unnamed module: " + module);
 521                     }
 522                 }
 523 
 524                 if ((accessFlags & ~(Modifier.PUBLIC | Modifier.IDENTITY)) != 0) {
 525                     throw new InternalError("proxy access flags must be Modifier.PUBLIC or 0");
 526                 }
 527             }
 528         }
 529 
 530         private static Class<?> defineProxyClass(ProxyClassContext context, List<Class<?>> interfaces) {
 531             /*
 532              * Choose a name for the proxy class to generate.
 533              */
 534             long num = nextUniqueNumber.getAndIncrement();
 535             String proxyName = context.packageName().isEmpty()
 536                                     ? proxyClassNamePrefix + num
 537                                     : context.packageName() + "." + proxyClassNamePrefix + num;
 538 
 539             ClassLoader loader = getLoader(context.module());
 540             trace(proxyName, context.module(), loader, interfaces);
 541 
 542             /*
 543              * Generate the specified proxy class.
 544              */
 545             byte[] proxyClassFile = ProxyGenerator.generateProxyClass(loader, proxyName, interfaces,
 546                                                                       context.accessFlags() | Modifier.FINAL | Modifier.IDENTITY);
 547             try {
 548                 Class<?> pc = JLA.defineClass(loader, proxyName, proxyClassFile,
 549                                               null, "__dynamic_proxy__");
 550                 reverseProxyCache.sub(pc).putIfAbsent(loader, Boolean.TRUE);
 551                 return pc;
 552             } catch (ClassFormatError e) {
 553                 /*
 554                  * A ClassFormatError here means that (barring bugs in the
 555                  * proxy class generation code) there was some other
 556                  * invalid aspect of the arguments supplied to the proxy
 557                  * class creation (such as virtual machine limitations
 558                  * exceeded).
 559                  */
 560                 throw new IllegalArgumentException(e.toString());
 561             }
 562         }
 563 
 564         /**
 565          * Test if given class is a class defined by
 566          * {@link #defineProxyClass(ProxyClassContext, List)}

 860             Module m = c.getModule();
 861             // add read edge and qualified export for the target module to access
 862             if (!target.canRead(m)) {
 863                 Modules.addReads(target, m);
 864             }
 865             String pn = c.getPackageName();
 866             if (!m.isExported(pn, target)) {
 867                 Modules.addExports(m, pn, target);
 868             }
 869         }
 870 
 871         /*
 872          * Ensure the given class is visible to the class loader.
 873          */
 874         private static void ensureVisible(ClassLoader ld, Class<?> c) {
 875             Class<?> type = null;
 876             try {
 877                 type = Class.forName(c.getName(), false, ld);
 878             } catch (ClassNotFoundException e) {
 879             }
 880             if (PrimitiveClass.asPrimaryType(type) != PrimitiveClass.asPrimaryType(c)) {
 881                 throw new IllegalArgumentException(c.getName() +
 882                         " referenced from a method is not visible from class loader");
 883             }
 884         }
 885 
 886         private static Class<?> getElementType(Class<?> type) {
 887             Class<?> e = type;
 888             while (e.isArray()) {
 889                 e = e.getComponentType();
 890             }
 891             return e;
 892         }
 893 
 894         private static final ClassLoaderValue<Module> dynProxyModules =
 895             new ClassLoaderValue<>();
 896         private static final AtomicInteger counter = new AtomicInteger();
 897 
 898         /*
 899          * Define a dynamic module with a package named $MODULE which
 900          * is unconditionally exported and another package named
< prev index next >