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.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&lt;?&gt; 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&lt;?&gt;[] { 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<>(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             if (!Modifier.isPublic(cl.getModifiers())) {
 731                 AccessController.doPrivileged(new PrivilegedAction<>() {
 732                     public Void run() {
 733                         cons.setAccessible(true);
 734                         return null;
 735                     }
 736                 });
 737             }
 738             return cons.newInstance(new Object[]{h});
 739         } catch (IllegalAccessException | InstantiationException | NoSuchMethodException e) {
 740             throw new InternalError(e.toString(), e);
 741         } catch (InvocationTargetException e) {
 742             Throwable t = e.getCause();
 743             if (t instanceof RuntimeException) {
 744                 throw (RuntimeException) t;
 745             } else {
 746                 throw new InternalError(t.toString(), t);
 747             }
 748         }
 749     }
 750 
 751     private static void checkNewProxyPermission(Class<?> caller, Class<?> proxyClass) {
 752         SecurityManager sm = System.getSecurityManager();
 753         if (sm != null) {
 754             if (ReflectUtil.isNonPublicProxyClass(proxyClass)) {
 755                 ClassLoader ccl = caller.getClassLoader();
 756                 ClassLoader pcl = proxyClass.getClassLoader();
 757 
 758                 // do permission check if the caller is in a different runtime package
 759                 // of the proxy class
 760                 int n = proxyClass.getName().lastIndexOf('.');
 761                 String pkg = (n == -1) ? "" : proxyClass.getName().substring(0, n);
 762 
 763                 n = caller.getName().lastIndexOf('.');
 764                 String callerPkg = (n == -1) ? "" : caller.getName().substring(0, n);
 765 
 766                 if (pcl != ccl || !pkg.equals(callerPkg)) {
 767                     sm.checkPermission(new ReflectPermission("newProxyInPackage." + pkg));
 768                 }
 769             }
 770         }
 771     }
 772 
 773     /**
 774      * Returns true if and only if the specified class was dynamically
 775      * generated to be a proxy class using the {@code getProxyClass}
 776      * method or the {@code newProxyInstance} method.
 777      *
 778      * <p>The reliability of this method is important for the ability
 779      * to use it to make security decisions, so its implementation should
 780      * not just test if the class in question extends {@code Proxy}.
 781      *
 782      * @param   cl the class to test
 783      * @return  {@code true} if the class is a proxy class and
 784      *          {@code false} otherwise
 785      * @throws  NullPointerException if {@code cl} is {@code null}
 786      */
 787     public static boolean isProxyClass(Class<?> cl) {
 788         return Proxy.class.isAssignableFrom(cl) && proxyClassCache.containsValue(cl);
 789     }
 790 
 791     /**
 792      * Returns the invocation handler for the specified proxy instance.
 793      *
 794      * @param   proxy the proxy instance to return the invocation handler for
 795      * @return  the invocation handler for the proxy instance
 796      * @throws  IllegalArgumentException if the argument is not a
 797      *          proxy instance
 798      * @throws  SecurityException if a security manager, <em>s</em>, is present
 799      *          and the caller's class loader is not the same as or an
 800      *          ancestor of the class loader for the invocation handler
 801      *          and invocation of {@link SecurityManager#checkPackageAccess
 802      *          s.checkPackageAccess()} denies access to the invocation
 803      *          handler's class.
 804      */
 805     @CallerSensitive
 806     public static InvocationHandler getInvocationHandler(Object proxy)
 807         throws IllegalArgumentException
 808     {
 809         /*
 810          * Verify that the object is actually a proxy instance.
 811          */
 812         if (!isProxyClass(proxy.getClass())) {
 813             throw new IllegalArgumentException("not a proxy instance");
 814         }
 815 
 816         final Proxy p = (Proxy) proxy;
 817         final InvocationHandler ih = p.h;
 818         if (System.getSecurityManager() != null) {
 819             Class<?> ihClass = ih.getClass();
 820             Class<?> caller = Reflection.getCallerClass();
 821             if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(),
 822                                                     ihClass.getClassLoader()))
 823             {
 824                 ReflectUtil.checkPackageAccess(ihClass);
 825             }
 826         }
 827 
 828         return ih;
 829     }
 830 
 831     private static native Class<?> defineClass0(ClassLoader loader, String name,
 832                                                 byte[] b, int off, int len);
 833 }