< prev index next >

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

Print this page




  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.access.JavaLangAccess;
  44 import jdk.internal.access.SharedSecrets;
  45 import jdk.internal.loader.BootLoader;
  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 },
  67  *                                          handler);
  68  * }</pre>
  69  *
  70  * <p>
  71  * A <em>proxy class</em> is a class created at runtime that implements a specified


  82  * containing the arguments.  The invocation handler processes the
  83  * encoded method invocation as appropriate and the result that it
  84  * returns will be returned as the result of the method invocation on
  85  * the proxy instance.
  86  *
  87  * <p>A proxy class has the following properties:
  88  *
  89  * <ul>
  90  * <li>The unqualified name of a proxy class is unspecified.  The space
  91  * of class names that begin with the string {@code "$Proxy"}
  92  * should be, however, reserved for proxy classes.
  93  *
  94  * <li>The package and module in which a proxy class is defined is specified
  95  * <a href="#membership">below</a>.
  96  *
  97  * <li>A proxy class is <em>final and non-abstract</em>.
  98  *
  99  * <li>A proxy class extends {@code java.lang.reflect.Proxy}.
 100  *
 101  * <li>A proxy class implements exactly the interfaces specified at its
 102  * creation, in the same order. Invoking {@link Class#getInterfaces getInterfaces}
 103  * on its {@code Class} object will return an array containing the same
 104  * list of interfaces (in the order specified at its creation), invoking
 105  * {@link Class#getMethods getMethods} on its {@code Class} object will return
 106  * an array of {@code Method} objects that include all of the
 107  * methods in those interfaces, and invoking {@code getMethod} will
 108  * find methods in the proxy interfaces as would be expected.
 109  *
 110  * <li>The {@link java.security.ProtectionDomain} of a proxy class
 111  * is the same as that of system classes loaded by the bootstrap class
 112  * loader, such as {@code java.lang.Object}, because the code for a
 113  * proxy class is generated by trusted system code.  This protection
 114  * domain will typically be granted {@code java.security.AllPermission}.
 115  *
 116  * <li>The {@link Proxy#isProxyClass Proxy.isProxyClass} method can be used
 117  * to determine if a given class is a proxy class.
 118  * </ul>
 119  *
 120  * <p>A proxy instance has the following properties:
 121  *
 122  * <ul>


 279  * @see         InvocationHandler
 280  * @since       1.3
 281  * @revised 9
 282  * @spec JPMS
 283  */
 284 public class Proxy implements java.io.Serializable {
 285     private static final long serialVersionUID = -2222568056686623797L;
 286 
 287     /** parameter types of a proxy class constructor */
 288     private static final Class<?>[] constructorParams =
 289         { InvocationHandler.class };
 290 
 291     /**
 292      * a cache of proxy constructors with
 293      * {@link Constructor#setAccessible(boolean) accessible} flag already set
 294      */
 295     private static final ClassLoaderValue<Constructor<?>> proxyCache =
 296         new ClassLoaderValue<>();
 297 
 298     /**







 299      * the invocation handler for this proxy instance.
 300      * @serial
 301      */
 302     protected InvocationHandler h;
 303 
 304     /**
 305      * Prohibits instantiation.
 306      */
 307     private Proxy() {
 308     }
 309 
 310     /**
 311      * Constructs a new {@code Proxy} instance from a subclass
 312      * (typically, a dynamic proxy class) with the specified value
 313      * for its invocation handler.
 314      *
 315      * @param  h the invocation handler for this proxy instance
 316      *
 317      * @throws NullPointerException if the given invocation handler, {@code h},
 318      *         is {@code null}.


 514             if (m.isNamed()) {
 515                 if (!m.getDescriptor().packages().contains(proxyPkg)) {
 516                     throw new InternalError(proxyPkg + " not exist in " + m.getName());
 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)}


1099          */
1100         if (!isProxyClass(proxy.getClass())) {
1101             throw new IllegalArgumentException("not a proxy instance");
1102         }
1103 
1104         final Proxy p = (Proxy) proxy;
1105         final InvocationHandler ih = p.h;
1106         if (System.getSecurityManager() != null) {
1107             Class<?> ihClass = ih.getClass();
1108             Class<?> caller = Reflection.getCallerClass();
1109             if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(),
1110                                                     ihClass.getClassLoader()))
1111             {
1112                 ReflectUtil.checkPackageAccess(ihClass);
1113             }
1114         }
1115 
1116         return ih;
1117     }
1118 
1119     private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[0];
1120     private static final String PROXY_PACKAGE_PREFIX = ReflectUtil.PROXY_PACKAGE;
1121 }


  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.access.JavaLangAccess;
  44 import jdk.internal.access.SharedSecrets;
  45 import jdk.internal.loader.BootLoader;
  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.GetBooleanAction;
  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 },
  68  *                                          handler);
  69  * }</pre>
  70  *
  71  * <p>
  72  * A <em>proxy class</em> is a class created at runtime that implements a specified


  83  * containing the arguments.  The invocation handler processes the
  84  * encoded method invocation as appropriate and the result that it
  85  * returns will be returned as the result of the method invocation on
  86  * the proxy instance.
  87  *
  88  * <p>A proxy class has the following properties:
  89  *
  90  * <ul>
  91  * <li>The unqualified name of a proxy class is unspecified.  The space
  92  * of class names that begin with the string {@code "$Proxy"}
  93  * should be, however, reserved for proxy classes.
  94  *
  95  * <li>The package and module in which a proxy class is defined is specified
  96  * <a href="#membership">below</a>.
  97  *
  98  * <li>A proxy class is <em>final and non-abstract</em>.
  99  *
 100  * <li>A proxy class extends {@code java.lang.reflect.Proxy}.
 101  *
 102  * <li>A proxy class implements exactly the interfaces specified at its
 103  * creation, in the same order. Invoking {@link Class#getInterfaces() getInterfaces}
 104  * on its {@code Class} object will return an array containing the same
 105  * list of interfaces (in the order specified at its creation), invoking
 106  * {@link Class#getMethods getMethods} on its {@code Class} object will return
 107  * an array of {@code Method} objects that include all of the
 108  * methods in those interfaces, and invoking {@code getMethod} will
 109  * find methods in the proxy interfaces as would be expected.
 110  *
 111  * <li>The {@link java.security.ProtectionDomain} of a proxy class
 112  * is the same as that of system classes loaded by the bootstrap class
 113  * loader, such as {@code java.lang.Object}, because the code for a
 114  * proxy class is generated by trusted system code.  This protection
 115  * domain will typically be granted {@code java.security.AllPermission}.
 116  *
 117  * <li>The {@link Proxy#isProxyClass Proxy.isProxyClass} method can be used
 118  * to determine if a given class is a proxy class.
 119  * </ul>
 120  *
 121  * <p>A proxy instance has the following properties:
 122  *
 123  * <ul>


 280  * @see         InvocationHandler
 281  * @since       1.3
 282  * @revised 9
 283  * @spec JPMS
 284  */
 285 public class Proxy implements java.io.Serializable {
 286     private static final long serialVersionUID = -2222568056686623797L;
 287 
 288     /** parameter types of a proxy class constructor */
 289     private static final Class<?>[] constructorParams =
 290         { InvocationHandler.class };
 291 
 292     /**
 293      * a cache of proxy constructors with
 294      * {@link Constructor#setAccessible(boolean) accessible} flag already set
 295      */
 296     private static final ClassLoaderValue<Constructor<?>> proxyCache =
 297         new ClassLoaderValue<>();
 298 
 299     /**
 300      * System property to revert to generation of proxy class files for version 1.5 (V49).
 301      * Set to "true" to generate v49 class file format.
 302      */
 303     private static final boolean PROXY_GENERATOR_V49 =
 304             GetBooleanAction.privilegedGetProperty("jdk.proxy.ProxyGenerator.v49");
 305 
 306     /**
 307      * the invocation handler for this proxy instance.
 308      * @serial
 309      */
 310     protected InvocationHandler h;
 311 
 312     /**
 313      * Prohibits instantiation.
 314      */
 315     private Proxy() {
 316     }
 317 
 318     /**
 319      * Constructs a new {@code Proxy} instance from a subclass
 320      * (typically, a dynamic proxy class) with the specified value
 321      * for its invocation handler.
 322      *
 323      * @param  h the invocation handler for this proxy instance
 324      *
 325      * @throws NullPointerException if the given invocation handler, {@code h},
 326      *         is {@code null}.


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


1108          */
1109         if (!isProxyClass(proxy.getClass())) {
1110             throw new IllegalArgumentException("not a proxy instance");
1111         }
1112 
1113         final Proxy p = (Proxy) proxy;
1114         final InvocationHandler ih = p.h;
1115         if (System.getSecurityManager() != null) {
1116             Class<?> ihClass = ih.getClass();
1117             Class<?> caller = Reflection.getCallerClass();
1118             if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(),
1119                                                     ihClass.getClassLoader()))
1120             {
1121                 ReflectUtil.checkPackageAccess(ihClass);
1122             }
1123         }
1124 
1125         return ih;
1126     }
1127 

1128     private static final String PROXY_PACKAGE_PREFIX = ReflectUtil.PROXY_PACKAGE;
1129 }
< prev index next >