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