1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This code is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License version 2 only, as
8  * published by the Free Software Foundation.  Oracle designates this
9  * particular file as subject to the "Classpath" exception as provided
10  * by Oracle in the LICENSE file that accompanied this code.
11  *
12  * This code is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15  * version 2 for more details (a copy is included in the LICENSE file that
16  * accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License version
19  * 2 along with this work; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21  *
22  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23  * or visit www.oracle.com if you need additional information or have any
24  * questions.
25  */
26 
27 package java.lang.reflect;
28 
29 
30 import dalvik.annotation.optimization.FastNative;
31 import java.lang.ref.Reference;
32 import java.lang.ref.WeakReference;
33 import java.security.Permission;
34 import java.security.PrivilegedAction;
35 import java.util.ArrayList;
36 import java.util.Arrays;
37 import java.util.Arrays;
38 import java.util.Collections;
39 import java.util.Comparator;
40 import java.util.HashMap;
41 import java.util.HashSet;
42 import java.util.IdentityHashMap;
43 import java.util.List;
44 import java.util.Map;
45 import java.util.Objects;
46 import java.util.Set;
47 import java.util.WeakHashMap;
48 import java.util.concurrent.atomic.AtomicLong;
49 import java.util.function.BiFunction;
50 import libcore.util.EmptyArray;
51 import sun.reflect.CallerSensitive;
52 import sun.reflect.misc.ReflectUtil;
53 import sun.security.util.SecurityConstants;
54 
55 /**
56  * {@code Proxy} provides static methods for creating dynamic proxy
57  * classes and instances, and it is also the superclass of all
58  * dynamic proxy classes created by those methods.
59  *
60  * <p>To create a proxy for some interface {@code Foo}:
61  * <pre>
62  *     InvocationHandler handler = new MyInvocationHandler(...);
63  *     Class&lt;?&gt; proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(), Foo.class);
64  *     Foo f = (Foo) proxyClass.getConstructor(InvocationHandler.class).
65  *                     newInstance(handler);
66  * </pre>
67  * or more simply:
68  * <pre>
69  *     Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
70  *                                          new Class&lt;?&gt;[] { Foo.class },
71  *                                          handler);
72  * </pre>
73  *
74  * <p>A <i>dynamic proxy class</i> (simply referred to as a <i>proxy
75  * class</i> below) is a class that implements a list of interfaces
76  * specified at runtime when the class is created, with behavior as
77  * described below.
78  *
79  * A <i>proxy interface</i> is such an interface that is implemented
80  * by a proxy class.
81  *
82  * A <i>proxy instance</i> is an instance of a proxy class.
83  *
84  * Each proxy instance has an associated <i>invocation handler</i>
85  * object, which implements the interface {@link InvocationHandler}.
86  * A method invocation on a proxy instance through one of its proxy
87  * interfaces will be dispatched to the {@link InvocationHandler#invoke
88  * invoke} method of the instance's invocation handler, passing the proxy
89  * instance, a {@code java.lang.reflect.Method} object identifying
90  * the method that was invoked, and an array of type {@code Object}
91  * containing the arguments.  The invocation handler processes the
92  * encoded method invocation as appropriate and the result that it
93  * returns will be returned as the result of the method invocation on
94  * the proxy instance.
95  *
96  * <p>A proxy class has the following properties:
97  *
98  * <ul>
99  * <li>Proxy classes are <em>public, final, and not abstract</em> if
100  * all proxy interfaces are public.</li>
101  *
102  * <li>Proxy classes are <em>non-public, final, and not abstract</em> if
103  * any of the proxy interfaces is non-public.</li>
104  *
105  * <li>The unqualified name of a proxy class is unspecified.  The space
106  * of class names that begin with the string {@code "$Proxy"}
107  * should be, however, reserved for proxy classes.
108  *
109  * <li>A proxy class extends {@code java.lang.reflect.Proxy}.
110  *
111  * <li>A proxy class implements exactly the interfaces specified at its
112  * creation, in the same order.
113  *
114  * <li>If a proxy class implements a non-public interface, then it will
115  * be defined in the same package as that interface.  Otherwise, the
116  * package of a proxy class is also unspecified.  Note that package
117  * sealing will not prevent a proxy class from being successfully defined
118  * in a particular package at runtime, and neither will classes already
119  * defined by the same class loader and the same package with particular
120  * signers.
121  *
122  * <li>Since a proxy class implements all of the interfaces specified at
123  * its creation, invoking {@code getInterfaces} on its
124  * {@code Class} object will return an array containing the same
125  * list of interfaces (in the order specified at its creation), invoking
126  * {@code getMethods} on its {@code Class} object will return
127  * an array of {@code Method} objects that include all of the
128  * methods in those interfaces, and invoking {@code getMethod} will
129  * find methods in the proxy interfaces as would be expected.
130  *
131  * <li>The {@link Proxy#isProxyClass Proxy.isProxyClass} method will
132  * return true if it is passed a proxy class-- a class returned by
133  * {@code Proxy.getProxyClass} or the class of an object returned by
134  * {@code Proxy.newProxyInstance}-- and false otherwise.
135  *
136  * <li>The {@code java.security.ProtectionDomain} of a proxy class
137  * is the same as that of system classes loaded by the bootstrap class
138  * loader, such as {@code java.lang.Object}, because the code for a
139  * proxy class is generated by trusted system code.  This protection
140  * domain will typically be granted
141  * {@code java.security.AllPermission}.
142  *
143  * <li>Each proxy class has one public constructor that takes one argument,
144  * an implementation of the interface {@link InvocationHandler}, to set
145  * the invocation handler for a proxy instance.  Rather than having to use
146  * the reflection API to access the public constructor, a proxy instance
147  * can be also be created by calling the {@link Proxy#newProxyInstance
148  * Proxy.newProxyInstance} method, which combines the actions of calling
149  * {@link Proxy#getProxyClass Proxy.getProxyClass} with invoking the
150  * constructor with an invocation handler.
151  * </ul>
152  *
153  * <p>A proxy instance has the following properties:
154  *
155  * <ul>
156  * <li>Given a proxy instance {@code proxy} and one of the
157  * interfaces implemented by its proxy class {@code Foo}, the
158  * following expression will return true:
159  * <pre>
160  *     {@code proxy instanceof Foo}
161  * </pre>
162  * and the following cast operation will succeed (rather than throwing
163  * a {@code ClassCastException}):
164  * <pre>
165  *     {@code (Foo) proxy}
166  * </pre>
167  *
168  * <li>Each proxy instance has an associated invocation handler, the one
169  * that was passed to its constructor.  The static
170  * {@link Proxy#getInvocationHandler Proxy.getInvocationHandler} method
171  * will return the invocation handler associated with the proxy instance
172  * passed as its argument.
173  *
174  * <li>An interface method invocation on a proxy instance will be
175  * encoded and dispatched to the invocation handler's {@link
176  * InvocationHandler#invoke invoke} method as described in the
177  * documentation for that method.
178  *
179  * <li>An invocation of the {@code hashCode},
180  * {@code equals}, or {@code toString} methods declared in
181  * {@code java.lang.Object} on a proxy instance will be encoded and
182  * dispatched to the invocation handler's {@code invoke} method in
183  * the same manner as interface method invocations are encoded and
184  * dispatched, as described above.  The declaring class of the
185  * {@code Method} object passed to {@code invoke} will be
186  * {@code java.lang.Object}.  Other public methods of a proxy
187  * instance inherited from {@code java.lang.Object} are not
188  * overridden by a proxy class, so invocations of those methods behave
189  * like they do for instances of {@code java.lang.Object}.
190  * </ul>
191  *
192  * <h3>Methods Duplicated in Multiple Proxy Interfaces</h3>
193  *
194  * <p>When two or more interfaces of a proxy class contain a method with
195  * the same name and parameter signature, the order of the proxy class's
196  * interfaces becomes significant.  When such a <i>duplicate method</i>
197  * is invoked on a proxy instance, the {@code Method} object passed
198  * to the invocation handler will not necessarily be the one whose
199  * declaring class is assignable from the reference type of the interface
200  * that the proxy's method was invoked through.  This limitation exists
201  * because the corresponding method implementation in the generated proxy
202  * class cannot determine which interface it was invoked through.
203  * Therefore, when a duplicate method is invoked on a proxy instance,
204  * the {@code Method} object for the method in the foremost interface
205  * that contains the method (either directly or inherited through a
206  * superinterface) in the proxy class's list of interfaces is passed to
207  * the invocation handler's {@code invoke} method, regardless of the
208  * reference type through which the method invocation occurred.
209  *
210  * <p>If a proxy interface contains a method with the same name and
211  * parameter signature as the {@code hashCode}, {@code equals},
212  * or {@code toString} methods of {@code java.lang.Object},
213  * when such a method is invoked on a proxy instance, the
214  * {@code Method} object passed to the invocation handler will have
215  * {@code java.lang.Object} as its declaring class.  In other words,
216  * the public, non-final methods of {@code java.lang.Object}
217  * logically precede all of the proxy interfaces for the determination of
218  * which {@code Method} object to pass to the invocation handler.
219  *
220  * <p>Note also that when a duplicate method is dispatched to an
221  * invocation handler, the {@code invoke} method may only throw
222  * checked exception types that are assignable to one of the exception
223  * types in the {@code throws} clause of the method in <i>all</i> of
224  * the proxy interfaces that it can be invoked through.  If the
225  * {@code invoke} method throws a checked exception that is not
226  * assignable to any of the exception types declared by the method in one
227  * of the proxy interfaces that it can be invoked through, then an
228  * unchecked {@code UndeclaredThrowableException} will be thrown by
229  * the invocation on the proxy instance.  This restriction means that not
230  * all of the exception types returned by invoking
231  * {@code getExceptionTypes} on the {@code Method} object
232  * passed to the {@code invoke} method can necessarily be thrown
233  * successfully by the {@code invoke} method.
234  *
235  * @author      Peter Jones
236  * @see         InvocationHandler
237  * @since       1.3
238  */
239 public class Proxy implements java.io.Serializable {
240 
241     private static final long serialVersionUID = -2222568056686623797L;
242 
243     /** prefix for all proxy class names */
244     private final static String proxyClassNamePrefix = "$Proxy";
245 
246     /** parameter types of a proxy class constructor */
247     private static final Class<?>[] constructorParams =
248         { InvocationHandler.class };
249 
250     /**
251      * a cache of proxy classes
252      */
253     private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
254         proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
255 
256     /**
257      * the invocation handler for this proxy instance.
258      * @serial
259      */
260     protected InvocationHandler h;
261 
262     /**
263      * Orders methods by their name, parameters, return type and inheritance relationship.
264      *
265      * @hide
266      */
267     private static final Comparator<Method> ORDER_BY_SIGNATURE_AND_SUBTYPE = new Comparator<Method>() {
268         @Override public int compare(Method a, Method b) {
269             int comparison = Method.ORDER_BY_SIGNATURE.compare(a, b);
270             if (comparison != 0) {
271                 return comparison;
272             }
273             Class<?> aClass = a.getDeclaringClass();
274             Class<?> bClass = b.getDeclaringClass();
275             if (aClass == bClass) {
276                 return 0;
277             } else if (aClass.isAssignableFrom(bClass)) {
278                 return 1;
279             } else if (bClass.isAssignableFrom(aClass)) {
280                 return -1;
281             } else {
282                 return 0;
283             }
284         }
285     };
286 
287     /**
288      * Prohibits instantiation.
289      */
Proxy()290     private Proxy() {
291     }
292 
293     /**
294      * Constructs a new {@code Proxy} instance from a subclass
295      * (typically, a dynamic proxy class) with the specified value
296      * for its invocation handler.
297      *
298      * @param  h the invocation handler for this proxy instance
299      *
300      * @throws NullPointerException if the given invocation handler, {@code h},
301      *         is {@code null}.
302      */
Proxy(InvocationHandler h)303     protected Proxy(InvocationHandler h) {
304         Objects.requireNonNull(h);
305         this.h = h;
306     }
307 
308     /**
309      * Returns the {@code java.lang.Class} object for a proxy class
310      * given a class loader and an array of interfaces.  The proxy class
311      * will be defined by the specified class loader and will implement
312      * all of the supplied interfaces.  If any of the given interfaces
313      * is non-public, the proxy class will be non-public. If a proxy class
314      * for the same permutation of interfaces has already been defined by the
315      * class loader, then the existing proxy class will be returned; otherwise,
316      * a proxy class for those interfaces will be generated dynamically
317      * and defined by the class loader.
318      *
319      * <p>There are several restrictions on the parameters that may be
320      * passed to {@code Proxy.getProxyClass}:
321      *
322      * <ul>
323      * <li>All of the {@code Class} objects in the
324      * {@code interfaces} array must represent interfaces, not
325      * classes or primitive types.
326      *
327      * <li>No two elements in the {@code interfaces} array may
328      * refer to identical {@code Class} objects.
329      *
330      * <li>All of the interface types must be visible by name through the
331      * specified class loader.  In other words, for class loader
332      * {@code cl} and every interface {@code i}, the following
333      * expression must be true:
334      * <pre>
335      *     Class.forName(i.getName(), false, cl) == i
336      * </pre>
337      *
338      * <li>All non-public interfaces must be in the same package;
339      * otherwise, it would not be possible for the proxy class to
340      * implement all of the interfaces, regardless of what package it is
341      * defined in.
342      *
343      * <li>For any set of member methods of the specified interfaces
344      * that have the same signature:
345      * <ul>
346      * <li>If the return type of any of the methods is a primitive
347      * type or void, then all of the methods must have that same
348      * return type.
349      * <li>Otherwise, one of the methods must have a return type that
350      * is assignable to all of the return types of the rest of the
351      * methods.
352      * </ul>
353      *
354      * <li>The resulting proxy class must not exceed any limits imposed
355      * on classes by the virtual machine.  For example, the VM may limit
356      * the number of interfaces that a class may implement to 65535; in
357      * that case, the size of the {@code interfaces} array must not
358      * exceed 65535.
359      * </ul>
360      *
361      * <p>If any of these restrictions are violated,
362      * {@code Proxy.getProxyClass} will throw an
363      * {@code IllegalArgumentException}.  If the {@code interfaces}
364      * array argument or any of its elements are {@code null}, a
365      * {@code NullPointerException} will be thrown.
366      *
367      * <p>Note that the order of the specified proxy interfaces is
368      * significant: two requests for a proxy class with the same combination
369      * of interfaces but in a different order will result in two distinct
370      * proxy classes.
371      *
372      * @param   loader the class loader to define the proxy class
373      * @param   interfaces the list of interfaces for the proxy class
374      *          to implement
375      * @return  a proxy class that is defined in the specified class loader
376      *          and that implements the specified interfaces
377      * @throws  IllegalArgumentException if any of the restrictions on the
378      *          parameters that may be passed to {@code getProxyClass}
379      *          are violated
380      * @throws  SecurityException if a security manager, <em>s</em>, is present
381      *          and any of the following conditions is met:
382      *          <ul>
383      *             <li> the given {@code loader} is {@code null} and
384      *             the caller's class loader is not {@code null} and the
385      *             invocation of {@link SecurityManager#checkPermission
386      *             s.checkPermission} with
387      *             {@code RuntimePermission("getClassLoader")} permission
388      *             denies access.</li>
389      *             <li> for each proxy interface, {@code intf},
390      *             the caller's class loader is not the same as or an
391      *             ancestor of the class loader for {@code intf} and
392      *             invocation of {@link SecurityManager#checkPackageAccess
393      *             s.checkPackageAccess()} denies access to {@code intf}.</li>
394      *          </ul>
395      * @throws  NullPointerException if the {@code interfaces} array
396      *          argument or any of its elements are {@code null}
397      */
398     @CallerSensitive
getProxyClass(ClassLoader loader, Class<?>... interfaces)399     public static Class<?> getProxyClass(ClassLoader loader,
400                                          Class<?>... interfaces)
401         throws IllegalArgumentException
402     {
403         return getProxyClass0(loader, interfaces);
404     }
405 
406     /**
407      * Generate a proxy class.  Must call the checkProxyAccess method
408      * to perform permission checks before calling this.
409      */
getProxyClass0(ClassLoader loader, Class<?>... interfaces)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 
Key1(Class<?> intf)438         Key1(Class<?> intf) {
439             super(intf);
440             this.hash = intf.hashCode();
441         }
442 
443         @Override
hashCode()444         public int hashCode() {
445             return hash;
446         }
447 
448         @Override
equals(Object obj)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 
Key2(Class<?> intf1, Class<?> intf2)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
hashCode()473         public int hashCode() {
474             return hash;
475         }
476 
477         @Override
equals(Object obj)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")
KeyX(Class<?>[] interfaces)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
hashCode()508         public int hashCode() {
509             return hash;
510         }
511 
512         @Override
equals(Object obj)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 
equals(WeakReference<Class<?>>[] refs1, WeakReference<Class<?>>[] refs2)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
apply(ClassLoader classLoader, Class<?>[] interfaces)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
apply(ClassLoader loader, Class<?>[] interfaces)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 the default package.
627                 proxyPkg = "";
628             }
629 
630             {
631                 // Android-changed: Generate the proxy directly instead of calling
632                 // through to ProxyGenerator.
633                 List<Method> methods = getMethods(interfaces);
634                 Collections.sort(methods, ORDER_BY_SIGNATURE_AND_SUBTYPE);
635                 validateReturnTypes(methods);
636                 List<Class<?>[]> exceptions = deduplicateAndGetExceptions(methods);
637 
638                 Method[] methodsArray = methods.toArray(new Method[methods.size()]);
639                 Class<?>[][] exceptionsArray = exceptions.toArray(new Class<?>[exceptions.size()][]);
640 
641                 /*
642                  * Choose a name for the proxy class to generate.
643                  */
644                 long num = nextUniqueNumber.getAndIncrement();
645                 String proxyName = proxyPkg + proxyClassNamePrefix + num;
646 
647                 return generateProxy(proxyName, interfaces, loader, methodsArray,
648                                      exceptionsArray);
649             }
650         }
651     }
652 
653     /**
654      * Remove methods that have the same name, parameters and return type. This
655      * computes the exceptions of each method; this is the intersection of the
656      * exceptions of equivalent methods.
657      *
658      * @param methods the methods to find exceptions for, ordered by name and
659      *     signature.
660      */
deduplicateAndGetExceptions(List<Method> methods)661     private static List<Class<?>[]> deduplicateAndGetExceptions(List<Method> methods) {
662         List<Class<?>[]> exceptions = new ArrayList<Class<?>[]>(methods.size());
663 
664         for (int i = 0; i < methods.size(); ) {
665             Method method = methods.get(i);
666             Class<?>[] exceptionTypes = method.getExceptionTypes();
667 
668             if (i > 0 && Method.ORDER_BY_SIGNATURE.compare(method, methods.get(i - 1)) == 0) {
669                 exceptions.set(i - 1, intersectExceptions(exceptions.get(i - 1), exceptionTypes));
670                 methods.remove(i);
671             } else {
672                 exceptions.add(exceptionTypes);
673                 i++;
674             }
675         }
676         return exceptions;
677     }
678 
679     /**
680      * Returns the exceptions that are declared in both {@code aExceptions} and
681      * {@code bExceptions}. If an exception type in one array is a subtype of an
682      * exception from the other, the subtype is included in the intersection.
683      */
intersectExceptions(Class<?>[] aExceptions, Class<?>[] bExceptions)684     private static Class<?>[] intersectExceptions(Class<?>[] aExceptions, Class<?>[] bExceptions) {
685         if (aExceptions.length == 0 || bExceptions.length == 0) {
686             return EmptyArray.CLASS;
687         }
688         if (Arrays.equals(aExceptions, bExceptions)) {
689             return aExceptions;
690         }
691         Set<Class<?>> intersection = new HashSet<Class<?>>();
692         for (Class<?> a : aExceptions) {
693             for (Class<?> b : bExceptions) {
694                 if (a.isAssignableFrom(b)) {
695                     intersection.add(b);
696                 } else if (b.isAssignableFrom(a)) {
697                     intersection.add(a);
698                 }
699             }
700         }
701         return intersection.toArray(new Class<?>[intersection.size()]);
702     }
703 
704     /**
705      * Throws if any two methods in {@code methods} have the same name and
706      * parameters but incompatible return types.
707      *
708      * @param methods the methods to find exceptions for, ordered by name and
709      *     signature.
710      */
validateReturnTypes(List<Method> methods)711     private static void validateReturnTypes(List<Method> methods) {
712         Method vs = null;
713         for (Method method : methods) {
714             if (vs == null || !vs.equalNameAndParameters(method)) {
715                 vs = method; // this has a different name or parameters
716                 continue;
717             }
718             Class<?> returnType = method.getReturnType();
719             Class<?> vsReturnType = vs.getReturnType();
720             if (returnType.isInterface() && vsReturnType.isInterface()) {
721                 // all interfaces are mutually compatible
722             } else if (vsReturnType.isAssignableFrom(returnType)) {
723                 vs = method; // the new return type is a subtype; use it instead
724             } else if (!returnType.isAssignableFrom(vsReturnType)) {
725                 throw new IllegalArgumentException("proxied interface methods have incompatible "
726                         + "return types:\n  " + vs + "\n  " + method);
727             }
728         }
729     }
730 
getMethods(Class<?>[] interfaces)731     private static List<Method> getMethods(Class<?>[] interfaces) {
732         List<Method> result = new ArrayList<Method>();
733         try {
734             result.add(Object.class.getMethod("equals", Object.class));
735             result.add(Object.class.getMethod("hashCode", EmptyArray.CLASS));
736             result.add(Object.class.getMethod("toString", EmptyArray.CLASS));
737         } catch (NoSuchMethodException e) {
738             throw new AssertionError();
739         }
740 
741         getMethodsRecursive(interfaces, result);
742         return result;
743     }
744 
745     /**
746      * Fills {@code proxiedMethods} with the methods of {@code interfaces} and
747      * the interfaces they extend. May contain duplicates.
748      */
getMethodsRecursive(Class<?>[] interfaces, List<Method> methods)749     private static void getMethodsRecursive(Class<?>[] interfaces, List<Method> methods) {
750         for (Class<?> i : interfaces) {
751             getMethodsRecursive(i.getInterfaces(), methods);
752             Collections.addAll(methods, i.getDeclaredMethods());
753         }
754     }
755 
756 
757     /**
758      * Returns an instance of a proxy class for the specified interfaces
759      * that dispatches method invocations to the specified invocation
760      * handler.
761      *
762      * <p>{@code Proxy.newProxyInstance} throws
763      * {@code IllegalArgumentException} for the same reasons that
764      * {@code Proxy.getProxyClass} does.
765      *
766      * @param   loader the class loader to define the proxy class
767      * @param   interfaces the list of interfaces for the proxy class
768      *          to implement
769      * @param   h the invocation handler to dispatch method invocations to
770      * @return  a proxy instance with the specified invocation handler of a
771      *          proxy class that is defined by the specified class loader
772      *          and that implements the specified interfaces
773      * @throws  IllegalArgumentException if any of the restrictions on the
774      *          parameters that may be passed to {@code getProxyClass}
775      *          are violated
776      * @throws  SecurityException if a security manager, <em>s</em>, is present
777      *          and any of the following conditions is met:
778      *          <ul>
779      *          <li> the given {@code loader} is {@code null} and
780      *               the caller's class loader is not {@code null} and the
781      *               invocation of {@link SecurityManager#checkPermission
782      *               s.checkPermission} with
783      *               {@code RuntimePermission("getClassLoader")} permission
784      *               denies access;</li>
785      *          <li> for each proxy interface, {@code intf},
786      *               the caller's class loader is not the same as or an
787      *               ancestor of the class loader for {@code intf} and
788      *               invocation of {@link SecurityManager#checkPackageAccess
789      *               s.checkPackageAccess()} denies access to {@code intf};</li>
790      *          <li> any of the given proxy interfaces is non-public and the
791      *               caller class is not in the same {@linkplain Package runtime package}
792      *               as the non-public interface and the invocation of
793      *               {@link SecurityManager#checkPermission s.checkPermission} with
794      *               {@code ReflectPermission("newProxyInPackage.{package name}")}
795      *               permission denies access.</li>
796      *          </ul>
797      * @throws  NullPointerException if the {@code interfaces} array
798      *          argument or any of its elements are {@code null}, or
799      *          if the invocation handler, {@code h}, is
800      *          {@code null}
801      */
802     @CallerSensitive
newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)803     public static Object newProxyInstance(ClassLoader loader,
804                                           Class<?>[] interfaces,
805                                           InvocationHandler h)
806         throws IllegalArgumentException
807     {
808         Objects.requireNonNull(h);
809 
810         final Class<?>[] intfs = interfaces.clone();
811         // Android-changed: sm is always null
812         // final SecurityManager sm = System.getSecurityManager();
813         // if (sm != null) {
814         //     checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
815         // }
816 
817         /*
818          * Look up or generate the designated proxy class.
819          */
820         Class<?> cl = getProxyClass0(loader, intfs);
821 
822         /*
823          * Invoke its constructor with the designated invocation handler.
824          */
825         try {
826             // Android-changed: sm is always null
827             // if (sm != null) {
828             //     checkNewProxyPermission(Reflection.getCallerClass(), cl);
829             // }
830 
831             final Constructor<?> cons = cl.getConstructor(constructorParams);
832             final InvocationHandler ih = h;
833             if (!Modifier.isPublic(cl.getModifiers())) {
834                 // Android-changed: Removed AccessController.doPrivileged
835                 cons.setAccessible(true);
836             }
837             return cons.newInstance(new Object[]{h});
838         } catch (IllegalAccessException|InstantiationException e) {
839             throw new InternalError(e.toString(), e);
840         } catch (InvocationTargetException e) {
841             Throwable t = e.getCause();
842             if (t instanceof RuntimeException) {
843                 throw (RuntimeException) t;
844             } else {
845                 throw new InternalError(t.toString(), t);
846             }
847         } catch (NoSuchMethodException e) {
848             throw new InternalError(e.toString(), e);
849         }
850     }
851 
852     /**
853      * Returns true if and only if the specified class was dynamically
854      * generated to be a proxy class using the {@code getProxyClass}
855      * method or the {@code newProxyInstance} method.
856      *
857      * <p>The reliability of this method is important for the ability
858      * to use it to make security decisions, so its implementation should
859      * not just test if the class in question extends {@code Proxy}.
860      *
861      * @param   cl the class to test
862      * @return  {@code true} if the class is a proxy class and
863      *          {@code false} otherwise
864      * @throws  NullPointerException if {@code cl} is {@code null}
865      */
isProxyClass(Class<?> cl)866     public static boolean isProxyClass(Class<?> cl) {
867         return Proxy.class.isAssignableFrom(cl) && proxyClassCache.containsValue(cl);
868     }
869 
870     /**
871      * Returns the invocation handler for the specified proxy instance.
872      *
873      * @param   proxy the proxy instance to return the invocation handler for
874      * @return  the invocation handler for the proxy instance
875      * @throws  IllegalArgumentException if the argument is not a
876      *          proxy instance
877      * @throws  SecurityException if a security manager, <em>s</em>, is present
878      *          and the caller's class loader is not the same as or an
879      *          ancestor of the class loader for the invocation handler
880      *          and invocation of {@link SecurityManager#checkPackageAccess
881      *          s.checkPackageAccess()} denies access to the invocation
882      *          handler's class.
883      */
884     @CallerSensitive
getInvocationHandler(Object proxy)885     public static InvocationHandler getInvocationHandler(Object proxy)
886         throws IllegalArgumentException
887     {
888         /*
889          * Verify that the object is actually a proxy instance.
890          */
891         if (!isProxyClass(proxy.getClass())) {
892             throw new IllegalArgumentException("not a proxy instance");
893         }
894 
895         final Proxy p = (Proxy) proxy;
896         final InvocationHandler ih = p.h;
897         // Android-changed, System.getSecurityManager() is always null
898         // if (System.getSecurityManager() != null) {
899         //     Class<?> ihClass = ih.getClass();
900         //     Class<?> caller = Reflection.getCallerClass();
901         //     if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(),
902         //                                             ihClass.getClassLoader()))
903         //     {
904         //         ReflectUtil.checkPackageAccess(ihClass);
905         //     }
906         // }
907         return ih;
908     }
909 
910     // Android-changed: helper for art native code.
invoke(Proxy proxy, Method method, Object[] args)911     private static Object invoke(Proxy proxy, Method method, Object[] args) throws Throwable {
912         InvocationHandler h = proxy.h;
913         return h.invoke(proxy, method, args);
914     }
915 
916     @FastNative
generateProxy(String name, Class<?>[] interfaces, ClassLoader loader, Method[] methods, Class<?>[][] exceptions)917     private static native Class<?> generateProxy(String name, Class<?>[] interfaces,
918                                                  ClassLoader loader, Method[] methods,
919                                                  Class<?>[][] exceptions);
920 
921     // Temporary methods.
reserved1()922     private static void reserved1() {};
reserved2()923     private static void reserved2() {};
924 }
925