1 /*
2 * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
3 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
4 *
5 *
6 *
7 *
8 *
9 *
10 *
11 *
12 *
13 *
14 *
15 *
16 *
17 *
18 *
19 *
20 *
21 *
22 *
23 *
24 */
25
26 package java.lang.reflect;
27
28 import java.lang.ref.WeakReference;
29 import java.security.AccessController;
30 import java.security.PrivilegedAction;
31 import java.util.Arrays;
32 import java.util.IdentityHashMap;
33 import java.util.Map;
34 import java.util.Objects;
35 import java.util.concurrent.atomic.AtomicLong;
36 import java.util.function.BiFunction;
37 import sun.misc.ProxyGenerator;
38 import sun.misc.VM;
39 import sun.reflect.CallerSensitive;
40 import sun.reflect.Reflection;
41 import sun.reflect.misc.ReflectUtil;
42 import sun.security.util.SecurityConstants;
43
44 /**
45 * {@code Proxy} provides static methods for creating dynamic proxy
46 * classes and instances, and it is also the superclass of all
47 * dynamic proxy classes created by those methods.
48 *
49 * <p>To create a proxy for some interface {@code Foo}:
50 * <pre>
51 * InvocationHandler handler = new MyInvocationHandler(...);
52 * Class<?> proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(), Foo.class);
53 * Foo f = (Foo) proxyClass.getConstructor(InvocationHandler.class).
54 * newInstance(handler);
55 * </pre>
56 * or more simply:
57 * <pre>
58 * Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
59 * new Class<?>[] { Foo.class },
60 * handler);
61 * </pre>
62 *
63 * <p>A <i>dynamic proxy class</i> (simply referred to as a <i>proxy
64 * class</i> below) is a class that implements a list of interfaces
65 * specified at runtime when the class is created, with behavior as
66 * described below.
67 *
68 * A <i>proxy interface</i> is such an interface that is implemented
69 * by a proxy class.
70 *
71 * A <i>proxy instance</i> is an instance of a proxy class.
72 *
73 * Each proxy instance has an associated <i>invocation handler</i>
74 * object, which implements the interface {@link InvocationHandler}.
75 * A method invocation on a proxy instance through one of its proxy
76 * interfaces will be dispatched to the {@link InvocationHandler#invoke
77 * invoke} method of the instance's invocation handler, passing the proxy
78 * instance, a {@code java.lang.reflect.Method} object identifying
79 * the method that was invoked, and an array of type {@code Object}
80 * containing the arguments. The invocation handler processes the
81 * encoded method invocation as appropriate and the result that it
82 * returns will be returned as the result of the method invocation on
83 * the proxy instance.
84 *
85 * <p>A proxy class has the following properties:
86 *
87 * <ul>
88 * <li>Proxy classes are <em>public, final, and not abstract</em> if
89 * all proxy interfaces are public.</li>
90 *
91 * <li>Proxy classes are <em>non-public, final, and not abstract</em> if
92 * any of the proxy interfaces is non-public.</li>
93 *
94 * <li>The unqualified name of a proxy class is unspecified. The space
95 * of class names that begin with the string {@code "$Proxy"}
96 * should be, however, reserved for proxy classes.
97 *
98 * <li>A proxy class extends {@code java.lang.reflect.Proxy}.
99 *
100 * <li>A proxy class implements exactly the interfaces specified at its
101 * creation, in the same order.
102 *
103 * <li>If a proxy class implements a non-public interface, then it will
104 * be defined in the same package as that interface. Otherwise, the
105 * package of a proxy class is also unspecified. Note that package
106 * sealing will not prevent a proxy class from being successfully defined
107 * in a particular package at runtime, and neither will classes already
108 * defined by the same class loader and the same package with particular
109 * signers.
110 *
111 * <li>Since a proxy class implements all of the interfaces specified at
112 * its creation, invoking {@code getInterfaces} on its
113 * {@code Class} object will return an array containing the same
114 * list of interfaces (in the order specified at its creation), invoking
115 * {@code getMethods} on its {@code Class} object will return
116 * an array of {@code Method} objects that include all of the
117 * methods in those interfaces, and invoking {@code getMethod} will
118 * find methods in the proxy interfaces as would be expected.
119 *
120 * <li>The {@link Proxy#isProxyClass Proxy.isProxyClass} method will
121 * return true if it is passed a proxy class-- a class returned by
122 * {@code Proxy.getProxyClass} or the class of an object returned by
123 * {@code Proxy.newProxyInstance}-- and false otherwise.
124 *
125 * <li>The {@code java.security.ProtectionDomain} of a proxy class
126 * is the same as that of system classes loaded by the bootstrap class
127 * loader, such as {@code java.lang.Object}, because the code for a
128 * proxy class is generated by trusted system code. This protection
129 * domain will typically be granted
130 * {@code java.security.AllPermission}.
131 *
132 * <li>Each proxy class has one public constructor that takes one argument,
133 * an implementation of the interface {@link InvocationHandler}, to set
134 * the invocation handler for a proxy instance. Rather than having to use
135 * the reflection API to access the public constructor, a proxy instance
136 * can be also be created by calling the {@link Proxy#newProxyInstance
137 * Proxy.newProxyInstance} method, which combines the actions of calling
138 * {@link Proxy#getProxyClass Proxy.getProxyClass} with invoking the
139 * constructor with an invocation handler.
140 * </ul>
141 *
142 * <p>A proxy instance has the following properties:
143 *
144 * <ul>
145 * <li>Given a proxy instance {@code proxy} and one of the
146 * interfaces implemented by its proxy class {@code Foo}, the
147 * following expression will return true:
148 * <pre>
149 * {@code proxy instanceof Foo}
150 * </pre>
151 * and the following cast operation will succeed (rather than throwing
152 * a {@code ClassCastException}):
153 * <pre>
154 * {@code (Foo) proxy}
155 * </pre>
156 *
157 * <li>Each proxy instance has an associated invocation handler, the one
158 * that was passed to its constructor. The static
159 * {@link Proxy#getInvocationHandler Proxy.getInvocationHandler} method
160 * will return the invocation handler associated with the proxy instance
161 * passed as its argument.
162 *
163 * <li>An interface method invocation on a proxy instance will be
164 * encoded and dispatched to the invocation handler's {@link
165 * InvocationHandler#invoke invoke} method as described in the
166 * documentation for that method.
167 *
168 * <li>An invocation of the {@code hashCode},
169 * {@code equals}, or {@code toString} methods declared in
170 * {@code java.lang.Object} on a proxy instance will be encoded and
171 * dispatched to the invocation handler's {@code invoke} method in
172 * the same manner as interface method invocations are encoded and
173 * dispatched, as described above. The declaring class of the
174 * {@code Method} object passed to {@code invoke} will be
175 * {@code java.lang.Object}. Other public methods of a proxy
176 * instance inherited from {@code java.lang.Object} are not
177 * overridden by a proxy class, so invocations of those methods behave
178 * like they do for instances of {@code java.lang.Object}.
179 * </ul>
180 *
181 * <h3>Methods Duplicated in Multiple Proxy Interfaces</h3>
182 *
183 * <p>When two or more interfaces of a proxy class contain a method with
184 * the same name and parameter signature, the order of the proxy class's
185 * interfaces becomes significant. When such a <i>duplicate method</i>
186 * is invoked on a proxy instance, the {@code Method} object passed
187 * to the invocation handler will not necessarily be the one whose
188 * declaring class is assignable from the reference type of the interface
189 * that the proxy's method was invoked through. This limitation exists
190 * because the corresponding method implementation in the generated proxy
191 * class cannot determine which interface it was invoked through.
192 * Therefore, when a duplicate method is invoked on a proxy instance,
193 * the {@code Method} object for the method in the foremost interface
194 * that contains the method (either directly or inherited through a
195 * superinterface) in the proxy class's list of interfaces is passed to
196 * the invocation handler's {@code invoke} method, regardless of the
197 * reference type through which the method invocation occurred.
198 *
199 * <p>If a proxy interface contains a method with the same name and
200 * parameter signature as the {@code hashCode}, {@code equals},
201 * or {@code toString} methods of {@code java.lang.Object},
202 * when such a method is invoked on a proxy instance, the
203 * {@code Method} object passed to the invocation handler will have
204 * {@code java.lang.Object} as its declaring class. In other words,
205 * the public, non-final methods of {@code java.lang.Object}
206 * logically precede all of the proxy interfaces for the determination of
207 * which {@code Method} object to pass to the invocation handler.
208 *
209 * <p>Note also that when a duplicate method is dispatched to an
210 * invocation handler, the {@code invoke} method may only throw
211 * checked exception types that are assignable to one of the exception
212 * types in the {@code throws} clause of the method in <i>all</i> of
213 * the proxy interfaces that it can be invoked through. If the
214 * {@code invoke} method throws a checked exception that is not
215 * assignable to any of the exception types declared by the method in one
216 * of the proxy interfaces that it can be invoked through, then an
217 * unchecked {@code UndeclaredThrowableException} will be thrown by
218 * the invocation on the proxy instance. This restriction means that not
219 * all of the exception types returned by invoking
220 * {@code getExceptionTypes} on the {@code Method} object
221 * passed to the {@code invoke} method can necessarily be thrown
222 * successfully by the {@code invoke} method.
223 *
224 * @author Peter Jones
225 * @see InvocationHandler
226 * @since 1.3
227 */
228 public class Proxy implements java.io.Serializable {
229
230 private static final long serialVersionUID = -2222568056686623797L;
231
232 /** parameter types of a proxy class constructor */
233 private static final Class<?>[] constructorParams =
234 { InvocationHandler.class };
235
236 /**
237 * a cache of proxy classes
238 */
239 private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
240 proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
241
242 /**
243 * the invocation handler for this proxy instance.
244 * @serial
245 */
246 protected InvocationHandler h;
247
248 /**
249 * Prohibits instantiation.
250 */
251 private Proxy() {
252 }
253
254 /**
255 * Constructs a new {@code Proxy} instance from a subclass
256 * (typically, a dynamic proxy class) with the specified value
257 * for its invocation handler.
258 *
259 * @param h the invocation handler for this proxy instance
260 *
261 * @throws NullPointerException if the given invocation handler, {@code h},
262 * is {@code null}.
263 */
264 protected Proxy(InvocationHandler h) {
265 Objects.requireNonNull(h);
266 this.h = h;
267 }
268
269 /**
270 * Returns the {@code java.lang.Class} object for a proxy class
271 * given a class loader and an array of interfaces. The proxy class
272 * will be defined by the specified class loader and will implement
273 * all of the supplied interfaces. If any of the given interfaces
274 * is non-public, the proxy class will be non-public. If a proxy class
275 * for the same permutation of interfaces has already been defined by the
276 * class loader, then the existing proxy class will be returned; otherwise,
277 * a proxy class for those interfaces will be generated dynamically
278 * and defined by the class loader.
279 *
280 * <p>There are several restrictions on the parameters that may be
281 * passed to {@code Proxy.getProxyClass}:
282 *
283 * <ul>
284 * <li>All of the {@code Class} objects in the
285 * {@code interfaces} array must represent interfaces, not
286 * classes or primitive types.
287 *
288 * <li>No two elements in the {@code interfaces} array may
289 * refer to identical {@code Class} objects.
290 *
291 * <li>All of the interface types must be visible by name through the
292 * specified class loader. In other words, for class loader
293 * {@code cl} and every interface {@code i}, the following
294 * expression must be true:
295 * <pre>
296 * Class.forName(i.getName(), false, cl) == i
297 * </pre>
298 *
299 * <li>All non-public interfaces must be in the same package;
300 * otherwise, it would not be possible for the proxy class to
301 * implement all of the interfaces, regardless of what package it is
302 * defined in.
303 *
304 * <li>For any set of member methods of the specified interfaces
305 * that have the same signature:
306 * <ul>
307 * <li>If the return type of any of the methods is a primitive
308 * type or void, then all of the methods must have that same
309 * return type.
310 * <li>Otherwise, one of the methods must have a return type that
311 * is assignable to all of the return types of the rest of the
312 * methods.
313 * </ul>
314 *
315 * <li>The resulting proxy class must not exceed any limits imposed
316 * on classes by the virtual machine. For example, the VM may limit
317 * the number of interfaces that a class may implement to 65535; in
318 * that case, the size of the {@code interfaces} array must not
319 * exceed 65535.
320 * </ul>
321 *
322 * <p>If any of these restrictions are violated,
323 * {@code Proxy.getProxyClass} will throw an
324 * {@code IllegalArgumentException}. If the {@code interfaces}
325 * array argument or any of its elements are {@code null}, a
326 * {@code NullPointerException} will be thrown.
327 *
328 * <p>Note that the order of the specified proxy interfaces is
329 * significant: two requests for a proxy class with the same combination
330 * of interfaces but in a different order will result in two distinct
331 * proxy classes.
332 *
333 * @param loader the class loader to define the proxy class
334 * @param interfaces the list of interfaces for the proxy class
335 * to implement
336 * @return a proxy class that is defined in the specified class loader
337 * and that implements the specified interfaces
338 * @throws IllegalArgumentException if any of the restrictions on the
339 * parameters that may be passed to {@code getProxyClass}
340 * are violated
341 * @throws SecurityException if a security manager, <em>s</em>, is present
342 * and any of the following conditions is met:
343 * <ul>
344 * <li> the given {@code loader} is {@code null} and
345 * the caller's class loader is not {@code null} and the
346 * invocation of {@link SecurityManager#checkPermission
347 * s.checkPermission} with
348 * {@code RuntimePermission("getClassLoader")} permission
349 * denies access.</li>
350 * <li> for each proxy interface, {@code intf},
351 * the caller's class loader is not the same as or an
352 * ancestor of the class loader for {@code intf} and
353 * invocation of {@link SecurityManager#checkPackageAccess
354 * s.checkPackageAccess()} denies access to {@code intf}.</li>
355 * </ul>
356
357 * @throws NullPointerException if the {@code interfaces} array
358 * argument or any of its elements are {@code null}
359 */
360 @CallerSensitive
361 public static Class<?> getProxyClass(ClassLoader loader,
362 Class<?>... interfaces)
363 throws IllegalArgumentException
364 {
365 final Class<?>[] intfs = interfaces.clone();
366 final SecurityManager sm = System.getSecurityManager();
367 if (sm != null) {
368 checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
369 }
370
371 return getProxyClass0(loader, intfs);
372 }
373
374 /*
375 * Check permissions required to create a Proxy class.
376 *
377 * To define a proxy class, it performs the access checks as in
378 * Class.forName (VM will invoke ClassLoader.checkPackageAccess):
379 * 1. "getClassLoader" permission check if loader == null
380 * 2. checkPackageAccess on the interfaces it implements
381 *
382 * To get a constructor and new instance of a proxy class, it performs
383 * the package access check on the interfaces it implements
384 * as in Class.getConstructor.
385 *
386 * If an interface is non-public, the proxy class must be defined by
387 * the defining loader of the interface. If the caller's class loader
388 * is not the same as the defining loader of the interface, the VM
389 * will throw IllegalAccessError when the generated proxy class is
390 * being defined via the defineClass0 method.
391 */
392 private static void checkProxyAccess(Class<?> caller,
393 ClassLoader loader,
394 Class<?>... interfaces)
395 {
396 SecurityManager sm = System.getSecurityManager();
397 if (sm != null) {
398 ClassLoader ccl = caller.getClassLoader();
399 if (VM.isSystemDomainLoader(loader) && !VM.isSystemDomainLoader(ccl)) {
400 sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
401 }
402 ReflectUtil.checkProxyPackageAccess(ccl, interfaces);
403 }
404 }
405
406 /**
407 * Generate a proxy class. Must call the checkProxyAccess method
408 * to perform permission checks before calling this.
409 */
410 private static Class<?> getProxyClass0(ClassLoader loader,
411 Class<?>... interfaces) {
412 if (interfaces.length > 65535) {
413 throw new IllegalArgumentException("interface limit exceeded");
414 }
415
416 // If the proxy class defined by the given loader implementing
417 // the given interfaces exists, this will simply return the cached copy;
418 // otherwise, it will create the proxy class via the ProxyClassFactory
419 return proxyClassCache.get(loader, interfaces);
420 }
421
422 /*
423 * a key used for proxy class with 0 implemented interfaces
424 */
425 private static final Object key0 = new Object();
426
427 /*
428 * Key1 and Key2 are optimized for the common use of dynamic proxies
429 * that implement 1 or 2 interfaces.
430 */
431
432 /*
433 * a key used for proxy class with 1 implemented interface
434 */
435 private static final class Key1 extends WeakReference<Class<?>> {
436 private final int hash;
437
438 Key1(Class<?> intf) {
439 super(intf);
440 this.hash = intf.hashCode();
441 }
442
443 @Override
444 public int hashCode() {
445 return hash;
446 }
447
448 @Override
449 public boolean equals(Object obj) {
450 Class<?> intf;
451 return this == obj ||
452 obj != null &&
453 obj.getClass() == Key1.class &&
454 (intf = get()) != null &&
455 intf == ((Key1) obj).get();
456 }
457 }
458
459 /*
460 * a key used for proxy class with 2 implemented interfaces
461 */
462 private static final class Key2 extends WeakReference<Class<?>> {
463 private final int hash;
464 private final WeakReference<Class<?>> ref2;
465
466 Key2(Class<?> intf1, Class<?> intf2) {
467 super(intf1);
468 hash = 31 * intf1.hashCode() + intf2.hashCode();
469 ref2 = new WeakReference<Class<?>>(intf2);
470 }
471
472 @Override
473 public int hashCode() {
474 return hash;
475 }
476
477 @Override
478 public boolean equals(Object obj) {
479 Class<?> intf1, intf2;
480 return this == obj ||
481 obj != null &&
482 obj.getClass() == Key2.class &&
483 (intf1 = get()) != null &&
484 intf1 == ((Key2) obj).get() &&
485 (intf2 = ref2.get()) != null &&
486 intf2 == ((Key2) obj).ref2.get();
487 }
488 }
489
490 /*
491 * a key used for proxy class with any number of implemented interfaces
492 * (used here for 3 or more only)
493 */
494 private static final class KeyX {
495 private final int hash;
496 private final WeakReference<Class<?>>[] refs;
497
498 @SuppressWarnings("unchecked")
499 KeyX(Class<?>[] interfaces) {
500 hash = Arrays.hashCode(interfaces);
501 refs = (WeakReference<Class<?>>[])new WeakReference<?>[interfaces.length];
502 for (int i = 0; i < interfaces.length; i++) {
503 refs[i] = new WeakReference<>(interfaces[i]);
504 }
505 }
506
507 @Override
508 public int hashCode() {
509 return hash;
510 }
511
512 @Override
513 public boolean equals(Object obj) {
514 return this == obj ||
515 obj != null &&
516 obj.getClass() == KeyX.class &&
517 equals(refs, ((KeyX) obj).refs);
518 }
519
520 private static boolean equals(WeakReference<Class<?>>[] refs1,
521 WeakReference<Class<?>>[] refs2) {
522 if (refs1.length != refs2.length) {
523 return false;
524 }
525 for (int i = 0; i < refs1.length; i++) {
526 Class<?> intf = refs1[i].get();
527 if (intf == null || intf != refs2[i].get()) {
528 return false;
529 }
530 }
531 return true;
532 }
533 }
534
535 /**
536 * A function that maps an array of interfaces to an optimal key where
537 * Class objects representing interfaces are weakly referenced.
538 */
539 private static final class KeyFactory
540 implements BiFunction<ClassLoader, Class<?>[], Object>
541 {
542 @Override
543 public Object apply(ClassLoader classLoader, Class<?>[] interfaces) {
544 switch (interfaces.length) {
545 case 1: return new Key1(interfaces[0]); // the most frequent
546 case 2: return new Key2(interfaces[0], interfaces[1]);
547 case 0: return key0;
548 default: return new KeyX(interfaces);
549 }
550 }
551 }
552
553 /**
554 * A factory function that generates, defines and returns the proxy class given
555 * the ClassLoader and array of interfaces.
556 */
557 private static final class ProxyClassFactory
558 implements BiFunction<ClassLoader, Class<?>[], Class<?>>
559 {
560 // prefix for all proxy class names
561 private static final String proxyClassNamePrefix = "$Proxy";
562
563 // next number to use for generation of unique proxy class names
564 private static final AtomicLong nextUniqueNumber = new AtomicLong();
565
566 @Override
567 public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
568
569 Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
570 for (Class<?> intf : interfaces) {
571 /*
572 * Verify that the class loader resolves the name of this
573 * interface to the same Class object.
574 */
575 Class<?> interfaceClass = null;
576 try {
577 interfaceClass = Class.forName(intf.getName(), false, loader);
578 } catch (ClassNotFoundException e) {
579 }
580 if (interfaceClass != intf) {
581 throw new IllegalArgumentException(
582 intf + " is not visible from class loader");
583 }
584 /*
585 * Verify that the Class object actually represents an
586 * interface.
587 */
588 if (!interfaceClass.isInterface()) {
589 throw new IllegalArgumentException(
590 interfaceClass.getName() + " is not an interface");
591 }
592 /*
593 * Verify that this interface is not a duplicate.
594 */
595 if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {
596 throw new IllegalArgumentException(
597 "repeated interface: " + interfaceClass.getName());
598 }
599 }
600
601 String proxyPkg = null; // package to define proxy class in
602 int accessFlags = Modifier.PUBLIC | Modifier.FINAL;
603
604 /*
605 * Record the package of a non-public proxy interface so that the
606 * proxy class will be defined in the same package. Verify that
607 * all non-public proxy interfaces are in the same package.
608 */
609 for (Class<?> intf : interfaces) {
610 int flags = intf.getModifiers();
611 if (!Modifier.isPublic(flags)) {
612 accessFlags = Modifier.FINAL;
613 String name = intf.getName();
614 int n = name.lastIndexOf('.');
615 String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
616 if (proxyPkg == null) {
617 proxyPkg = pkg;
618 } else if (!pkg.equals(proxyPkg)) {
619 throw new IllegalArgumentException(
620 "non-public interfaces from different packages");
621 }
622 }
623 }
624
625 if (proxyPkg == null) {
626 // if no non-public proxy interfaces, use com.sun.proxy package
627 proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
628 }
629
630 /*
631 * Choose a name for the proxy class to generate.
632 */
633 long num = nextUniqueNumber.getAndIncrement();
634 String proxyName = proxyPkg + proxyClassNamePrefix + num;
635
636 /*
637 * Generate the specified proxy class.
638 */
639 byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
640 proxyName, interfaces, accessFlags);
641 try {
642 return defineClass0(loader, proxyName,
643 proxyClassFile, 0, proxyClassFile.length);
644 } catch (ClassFormatError e) {
645 /*
646 * A ClassFormatError here means that (barring bugs in the
647 * proxy class generation code) there was some other
648 * invalid aspect of the arguments supplied to the proxy
649 * class creation (such as virtual machine limitations
650 * exceeded).
651 */
652 throw new IllegalArgumentException(e.toString());
653 }
654 }
655 }
656
657 /**
658 * Returns an instance of a proxy class for the specified interfaces
659 * that dispatches method invocations to the specified invocation
660 * handler.
661 *
662 * <p>{@code Proxy.newProxyInstance} throws
663 * {@code IllegalArgumentException} for the same reasons that
664 * {@code Proxy.getProxyClass} does.
665 *
666 * @param loader the class loader to define the proxy class
667 * @param interfaces the list of interfaces for the proxy class
668 * to implement
669 * @param h the invocation handler to dispatch method invocations to
670 * @return a proxy instance with the specified invocation handler of a
671 * proxy class that is defined by the specified class loader
672 * and that implements the specified interfaces
673 * @throws IllegalArgumentException if any of the restrictions on the
674 * parameters that may be passed to {@code getProxyClass}
675 * are violated
676 * @throws SecurityException if a security manager, <em>s</em>, is present
677 * and any of the following conditions is met:
678 * <ul>
679 * <li> the given {@code loader} is {@code null} and
680 * the caller's class loader is not {@code null} and the
681 * invocation of {@link SecurityManager#checkPermission
682 * s.checkPermission} with
683 * {@code RuntimePermission("getClassLoader")} permission
684 * denies access;</li>
685 * <li> for each proxy interface, {@code intf},
686 * the caller's class loader is not the same as or an
687 * ancestor of the class loader for {@code intf} and
688 * invocation of {@link SecurityManager#checkPackageAccess
689 * s.checkPackageAccess()} denies access to {@code intf};</li>
690 * <li> any of the given proxy interfaces is non-public and the
691 * caller class is not in the same {@linkplain Package runtime package}
692 * as the non-public interface and the invocation of
693 * {@link SecurityManager#checkPermission s.checkPermission} with
694 * {@code ReflectPermission("newProxyInPackage.{package name}")}
695 * permission denies access.</li>
696 * </ul>
697 * @throws NullPointerException if the {@code interfaces} array
698 * argument or any of its elements are {@code null}, or
699 * if the invocation handler, {@code h}, is
700 * {@code null}
701 */
702 @CallerSensitive
703 public static Object newProxyInstance(ClassLoader loader,
704 Class<?>[] interfaces,
705 InvocationHandler h)
706 throws IllegalArgumentException
707 {
708 Objects.requireNonNull(h);
709
710 final Class<?>[] intfs = interfaces.clone();
711 final SecurityManager sm = System.getSecurityManager();
712 if (sm != null) {
713 checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
714 }
715
716 /*
717 * Look up or generate the designated proxy class.
718 */
719 Class<?> cl = getProxyClass0(loader, intfs);
720
721 /*
722 * Invoke its constructor with the designated invocation handler.
723 */
724 try {
725 if (sm != null) {
726 checkNewProxyPermission(Reflection.getCallerClass(), cl);
727 }
728
729 final Constructor<?> cons = cl.getConstructor(constructorParams);
730 final InvocationHandler ih = h;
731 if (!Modifier.isPublic(cl.getModifiers())) {
732 AccessController.doPrivileged(new PrivilegedAction<Void>() {
733 public Void run() {
734 cons.setAccessible(true);
735 return null;
736 }
737 });
738 }
739 return cons.newInstance(new Object[]{h});
740 } catch (IllegalAccessException|InstantiationException e) {
741 throw new InternalError(e.toString(), e);
742 } catch (InvocationTargetException e) {
743 Throwable t = e.getCause();
744 if (t instanceof RuntimeException) {
745 throw (RuntimeException) t;
746 } else {
747 throw new InternalError(t.toString(), t);
748 }
749 } catch (NoSuchMethodException e) {
750 throw new InternalError(e.toString(), e);
751 }
752 }
753
754 private static void checkNewProxyPermission(Class<?> caller, Class<?> proxyClass) {
755 SecurityManager sm = System.getSecurityManager();
756 if (sm != null) {
757 if (ReflectUtil.isNonPublicProxyClass(proxyClass)) {
758 ClassLoader ccl = caller.getClassLoader();
759 ClassLoader pcl = proxyClass.getClassLoader();
760
761 // do permission check if the caller is in a different runtime package
762 // of the proxy class
763 int n = proxyClass.getName().lastIndexOf('.');
764 String pkg = (n == -1) ? "" : proxyClass.getName().substring(0, n);
765
766 n = caller.getName().lastIndexOf('.');
767 String callerPkg = (n == -1) ? "" : caller.getName().substring(0, n);
768
769 if (pcl != ccl || !pkg.equals(callerPkg)) {
770 sm.checkPermission(new ReflectPermission("newProxyInPackage." + pkg));
771 }
772 }
773 }
774 }
775
776 /**
777 * Returns true if and only if the specified class was dynamically
778 * generated to be a proxy class using the {@code getProxyClass}
779 * method or the {@code newProxyInstance} method.
780 *
781 * <p>The reliability of this method is important for the ability
782 * to use it to make security decisions, so its implementation should
783 * not just test if the class in question extends {@code Proxy}.
784 *
785 * @param cl the class to test
786 * @return {@code true} if the class is a proxy class and
787 * {@code false} otherwise
788 * @throws NullPointerException if {@code cl} is {@code null}
789 */
790 public static boolean isProxyClass(Class<?> cl) {
791 return Proxy.class.isAssignableFrom(cl) && proxyClassCache.containsValue(cl);
792 }
793
794 /**
795 * Returns the invocation handler for the specified proxy instance.
796 *
797 * @param proxy the proxy instance to return the invocation handler for
798 * @return the invocation handler for the proxy instance
799 * @throws IllegalArgumentException if the argument is not a
800 * proxy instance
801 * @throws SecurityException if a security manager, <em>s</em>, is present
802 * and the caller's class loader is not the same as or an
803 * ancestor of the class loader for the invocation handler
804 * and invocation of {@link SecurityManager#checkPackageAccess
805 * s.checkPackageAccess()} denies access to the invocation
806 * handler's class.
807 */
808 @CallerSensitive
809 public static InvocationHandler getInvocationHandler(Object proxy)
810 throws IllegalArgumentException
811 {
812 /*
813 * Verify that the object is actually a proxy instance.
814 */
815 if (!isProxyClass(proxy.getClass())) {
816 throw new IllegalArgumentException("not a proxy instance");
817 }
818
819 final Proxy p = (Proxy) proxy;
820 final InvocationHandler ih = p.h;
821 if (System.getSecurityManager() != null) {
822 Class<?> ihClass = ih.getClass();
823 Class<?> caller = Reflection.getCallerClass();
824 if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(),
825 ihClass.getClassLoader()))
826 {
827 ReflectUtil.checkPackageAccess(ihClass);
828 }
829 }
830
831 return ih;
832 }
833
834 private static native Class<?> defineClass0(ClassLoader loader, String name,
835 byte[] b, int off, int len);
836 }
837