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 }
|