1 /*
   2  * Copyright (c) 1999, 2010, 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.Reference;
  29 import java.lang.ref.WeakReference;
  30 import java.security.AccessController;
  31 import java.security.Permission;
  32 import java.security.PrivilegedAction;
  33 import java.util.Arrays;
  34 import java.util.Collections;
  35 import java.util.HashMap;
  36 import java.util.HashSet;
  37 import java.util.Map;
  38 import java.util.Set;
  39 import java.util.List;
  40 import java.util.WeakHashMap;
  41 import sun.misc.ProxyGenerator;
  42 import sun.reflect.Reflection;
  43 import sun.reflect.misc.ReflectUtil;
  44 import sun.security.util.SecurityConstants;
  45 
  46 /**
  47  * {@code Proxy} provides static methods for creating dynamic proxy
  48  * classes and instances, and it is also the superclass of all
  49  * dynamic proxy classes created by those methods.
  50  *
  51  * <p>To create a proxy for some interface {@code Foo}:
  52  * <pre>
  53  *     InvocationHandler handler = new MyInvocationHandler(...);
  54  *     Class proxyClass = Proxy.getProxyClass(
  55  *         Foo.class.getClassLoader(), new Class[] { Foo.class });
  56  *     Foo f = (Foo) proxyClass.
  57  *         getConstructor(new Class[] { InvocationHandler.class }).
  58  *         newInstance(new Object[] { handler });
  59  * </pre>
  60  * or more simply:
  61  * <pre>
  62  *     Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
  63  *                                          new Class[] { Foo.class },
  64  *                                          handler);
  65  * </pre>
  66  *
  67  * <p>A <i>dynamic proxy class</i> (simply referred to as a <i>proxy
  68  * class</i> below) is a class that implements a list of interfaces
  69  * specified at runtime when the class is created, with behavior as
  70  * described below.
  71  *
  72  * A <i>proxy interface</i> is such an interface that is implemented
  73  * by a proxy class.
  74  *
  75  * A <i>proxy instance</i> is an instance of a proxy class.
  76  *
  77  * Each proxy instance has an associated <i>invocation handler</i>
  78  * object, which implements the interface {@link InvocationHandler}.
  79  * A method invocation on a proxy instance through one of its proxy
  80  * interfaces will be dispatched to the {@link InvocationHandler#invoke
  81  * invoke} method of the instance's invocation handler, passing the proxy
  82  * instance, a {@code java.lang.reflect.Method} object identifying
  83  * the method that was invoked, and an array of type {@code Object}
  84  * containing the arguments.  The invocation handler processes the
  85  * encoded method invocation as appropriate and the result that it
  86  * returns will be returned as the result of the method invocation on
  87  * the proxy instance.
  88  *
  89  * <p>A proxy class has the following properties:
  90  *
  91  * <ul>
  92  * <li>Proxy classes are public, final, and not abstract.
  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     /** prefix for all proxy class names */
 233     private final static String proxyClassNamePrefix = "$Proxy";
 234 
 235     /** parameter types of a proxy class constructor */
 236     private final static Class[] constructorParams =
 237         { InvocationHandler.class };
 238 
 239     /** maps a class loader to the proxy class cache for that loader */
 240     private static Map<ClassLoader, Map<List<String>, Object>> loaderToCache
 241         = new WeakHashMap<>();
 242 
 243     /** marks that a particular proxy class is currently being generated */
 244     private static Object pendingGenerationMarker = new Object();
 245 
 246     /** next number to use for generation of unique proxy class names */
 247     private static long nextUniqueNumber = 0;
 248     private static Object nextUniqueNumberLock = new Object();
 249 
 250     /** set of all generated proxy classes, for isProxyClass implementation */
 251     private static Map<Class<?>, Void> proxyClasses =
 252         Collections.synchronizedMap(new WeakHashMap<Class<?>, Void>());
 253 
 254     /**
 255      * the invocation handler for this proxy instance.
 256      * @serial
 257      */
 258     protected InvocationHandler h;
 259 
 260     /**
 261      * Prohibits instantiation.
 262      */
 263     private Proxy() {
 264     }
 265 
 266     /**
 267      * Constructs a new {@code Proxy} instance from a subclass
 268      * (typically, a dynamic proxy class) with the specified value
 269      * for its invocation handler.
 270      *
 271      * @param   h the invocation handler for this proxy instance
 272      */
 273     protected Proxy(InvocationHandler h) {
 274         doNewInstanceCheck();
 275         this.h = h;
 276     }
 277 
 278     private static class ProxyAccessHelper {
 279         // The permission is implementation specific.
 280         static final Permission PROXY_PERMISSION =
 281             new ReflectPermission("proxyConstructorNewInstance");
 282         // These system properties are defined to provide a short-term
 283         // workaround if customers need to disable the new security checks.
 284         static final boolean allowNewInstance;
 285         static final boolean allowNullLoader;
 286         static {
 287             allowNewInstance = getBooleanProperty("sun.reflect.proxy.allowsNewInstance");
 288             allowNullLoader = getBooleanProperty("sun.reflect.proxy.allowsNullLoader");
 289         }
 290 
 291         private static boolean getBooleanProperty(final String key) {
 292             String s = AccessController.doPrivileged(new PrivilegedAction<String>() {
 293                 public String run() {
 294                     return System.getProperty(key);
 295                 }
 296             });
 297             return Boolean.valueOf(s);
 298         }
 299 
 300         static boolean needsNewInstanceCheck(Class<?> proxyClass) {
 301             if (!Proxy.isProxyClass(proxyClass) || allowNewInstance) {
 302                 return false;
 303             }
 304 
 305             if (proxyClass.getName().startsWith(ReflectUtil.PROXY_PACKAGE + ".")) {
 306                 // all proxy interfaces are public
 307                 return false;
 308             }
 309             for (Class<?> intf : proxyClass.getInterfaces()) {
 310                 if (!Modifier.isPublic(intf.getModifiers())) {
 311                     return true;
 312                 }
 313             }
 314             return false;
 315         }
 316     }
 317 
 318     /*
 319      * Access check on a proxy class that implements any non-public interface.
 320      *
 321      * @throws  SecurityException if a security manager exists, and
 322      *          the caller does not have the permission.
 323      */
 324     private void doNewInstanceCheck() {
 325         SecurityManager sm = System.getSecurityManager();
 326         Class<?> proxyClass = this.getClass();
 327         if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(proxyClass)) {
 328             try {
 329                 sm.checkPermission(ProxyAccessHelper.PROXY_PERMISSION);
 330             } catch (SecurityException e) {
 331                 throw new SecurityException("Not allowed to construct a Proxy "
 332                         + "instance that implements a non-public interface", e);
 333             }
 334         }
 335     }
 336 
 337     /**
 338      * Returns the {@code java.lang.Class} object for a proxy class
 339      * given a class loader and an array of interfaces.  The proxy class
 340      * will be defined by the specified class loader and will implement
 341      * all of the supplied interfaces.  If a proxy class for the same
 342      * permutation of interfaces has already been defined by the class
 343      * loader, then the existing proxy class will be returned; otherwise,
 344      * a proxy class for those interfaces will be generated dynamically
 345      * and defined by the class loader.
 346      *
 347      * <p>There are several restrictions on the parameters that may be
 348      * passed to {@code Proxy.getProxyClass}:
 349      *
 350      * <ul>
 351      * <li>All of the {@code Class} objects in the
 352      * {@code interfaces} array must represent interfaces, not
 353      * classes or primitive types.
 354      *
 355      * <li>No two elements in the {@code interfaces} array may
 356      * refer to identical {@code Class} objects.
 357      *
 358      * <li>All of the interface types must be visible by name through the
 359      * specified class loader.  In other words, for class loader
 360      * {@code cl} and every interface {@code i}, the following
 361      * expression must be true:
 362      * <pre>
 363      *     Class.forName(i.getName(), false, cl) == i
 364      * </pre>
 365      *
 366      * <li>All non-public interfaces must be in the same package;
 367      * otherwise, it would not be possible for the proxy class to
 368      * implement all of the interfaces, regardless of what package it is
 369      * defined in.
 370      *
 371      * <li>For any set of member methods of the specified interfaces
 372      * that have the same signature:
 373      * <ul>
 374      * <li>If the return type of any of the methods is a primitive
 375      * type or void, then all of the methods must have that same
 376      * return type.
 377      * <li>Otherwise, one of the methods must have a return type that
 378      * is assignable to all of the return types of the rest of the
 379      * methods.
 380      * </ul>
 381      *
 382      * <li>The resulting proxy class must not exceed any limits imposed
 383      * on classes by the virtual machine.  For example, the VM may limit
 384      * the number of interfaces that a class may implement to 65535; in
 385      * that case, the size of the {@code interfaces} array must not
 386      * exceed 65535.
 387      * </ul>
 388      *
 389      * <p>If any of these restrictions are violated,
 390      * {@code Proxy.getProxyClass} will throw an
 391      * {@code IllegalArgumentException}.  If the {@code interfaces}
 392      * array argument or any of its elements are {@code null}, a
 393      * {@code NullPointerException} will be thrown.
 394      *
 395      * <p>Note that the order of the specified proxy interfaces is
 396      * significant: two requests for a proxy class with the same combination
 397      * of interfaces but in a different order will result in two distinct
 398      * proxy classes.
 399      *
 400      * @param   loader the class loader to define the proxy class
 401      * @param   interfaces the list of interfaces for the proxy class
 402      *          to implement
 403      * @return  a proxy class that is defined in the specified class loader
 404      *          and that implements the specified interfaces
 405      * @throws  IllegalArgumentException if any of the restrictions on the
 406      *          parameters that may be passed to {@code getProxyClass}
 407      *          are violated
 408      * @throws  NullPointerException if the {@code interfaces} array
 409      *          argument or any of its elements are {@code null}
 410      */
 411     public static Class<?> getProxyClass(ClassLoader loader,
 412                                          Class<?>... interfaces)
 413         throws IllegalArgumentException
 414     {
 415         return getProxyClass0(loader, interfaces); // stack walk magic: do not refactor
 416     }
 417 
 418     private static void checkProxyLoader(ClassLoader ccl,
 419                                          ClassLoader loader)
 420     {
 421         SecurityManager sm = System.getSecurityManager();
 422         if (sm != null) {
 423             if (loader == null && ccl != null) {
 424                 if (!ProxyAccessHelper.allowNullLoader) {
 425                     sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
 426                 }
 427             }
 428         }
 429     }
 430 
 431     /*
 432      * Generate a proxy class (caller-sensitive).
 433      *
 434      * To define a proxy class, it performs the access checks as in
 435      * Class.forName (VM will invoke ClassLoader.checkPackageAccess):
 436      * 1. "getClassLoader" permission check if loader == null
 437      * 2. checkPackageAccess on the interfaces it implements
 438      *
 439      * To get a constructor and new instance of a proxy class, it performs
 440      * the package access check on the interfaces it implements
 441      * as in Class.getConstructor.
 442      *
 443      * If an interface is non-public, the proxy class must be defined by
 444      * the defining loader of the interface.  If the caller's class loader
 445      * is not the same as the defining loader of the interface, the VM
 446      * will throw IllegalAccessError when the generated proxy class is
 447      * being defined via the defineClass0 method.
 448      */
 449     private static Class<?> getProxyClass0(ClassLoader loader,
 450                                            Class<?>... interfaces) {
 451         SecurityManager sm = System.getSecurityManager();
 452         if (sm != null) {
 453             final int CALLER_FRAME = 3; // 0: Reflection, 1: getProxyClass0 2: Proxy 3: caller
 454             final Class<?> caller = Reflection.getCallerClass(CALLER_FRAME);
 455             final ClassLoader ccl = caller.getClassLoader();
 456             checkProxyLoader(ccl, loader);
 457             ReflectUtil.checkProxyPackageAccess(ccl, interfaces);
 458         }
 459 
 460         if (interfaces.length > 65535) {
 461             throw new IllegalArgumentException("interface limit exceeded");
 462         }
 463 
 464         Class<?> proxyClass = null;
 465 
 466         /* collect interface names to use as key for proxy class cache */
 467         String[] interfaceNames = new String[interfaces.length];
 468 
 469         // for detecting duplicates
 470         Set<Class<?>> interfaceSet = new HashSet<>();
 471 
 472         for (int i = 0; i < interfaces.length; i++) {
 473             /*
 474              * Verify that the class loader resolves the name of this
 475              * interface to the same Class object.
 476              */
 477             String interfaceName = interfaces[i].getName();
 478             Class<?> interfaceClass = null;
 479             try {
 480                 interfaceClass = Class.forName(interfaceName, false, loader);
 481             } catch (ClassNotFoundException e) {
 482             }
 483             if (interfaceClass != interfaces[i]) {
 484                 throw new IllegalArgumentException(
 485                     interfaces[i] + " is not visible from class loader");
 486             }
 487 
 488             /*
 489              * Verify that the Class object actually represents an
 490              * interface.
 491              */
 492             if (!interfaceClass.isInterface()) {
 493                 throw new IllegalArgumentException(
 494                     interfaceClass.getName() + " is not an interface");
 495             }
 496 
 497             /*
 498              * Verify that this interface is not a duplicate.
 499              */
 500             if (interfaceSet.contains(interfaceClass)) {
 501                 throw new IllegalArgumentException(
 502                     "repeated interface: " + interfaceClass.getName());
 503             }
 504             interfaceSet.add(interfaceClass);
 505 
 506             interfaceNames[i] = interfaceName;
 507         }
 508 
 509         /*
 510          * Using string representations of the proxy interfaces as
 511          * keys in the proxy class cache (instead of their Class
 512          * objects) is sufficient because we require the proxy
 513          * interfaces to be resolvable by name through the supplied
 514          * class loader, and it has the advantage that using a string
 515          * representation of a class makes for an implicit weak
 516          * reference to the class.
 517          */
 518         List<String> key = Arrays.asList(interfaceNames);
 519 
 520         /*
 521          * Find or create the proxy class cache for the class loader.
 522          */
 523         Map<List<String>, Object> cache;
 524         synchronized (loaderToCache) {
 525             cache = loaderToCache.get(loader);
 526             if (cache == null) {
 527                 cache = new HashMap<>();
 528                 loaderToCache.put(loader, cache);
 529             }
 530             /*
 531              * This mapping will remain valid for the duration of this
 532              * method, without further synchronization, because the mapping
 533              * will only be removed if the class loader becomes unreachable.
 534              */
 535         }
 536 
 537         /*
 538          * Look up the list of interfaces in the proxy class cache using
 539          * the key.  This lookup will result in one of three possible
 540          * kinds of values:
 541          *     null, if there is currently no proxy class for the list of
 542          *         interfaces in the class loader,
 543          *     the pendingGenerationMarker object, if a proxy class for the
 544          *         list of interfaces is currently being generated,
 545          *     or a weak reference to a Class object, if a proxy class for
 546          *         the list of interfaces has already been generated.
 547          */
 548         synchronized (cache) {
 549             /*
 550              * Note that we need not worry about reaping the cache for
 551              * entries with cleared weak references because if a proxy class
 552              * has been garbage collected, its class loader will have been
 553              * garbage collected as well, so the entire cache will be reaped
 554              * from the loaderToCache map.
 555              */
 556             do {
 557                 Object value = cache.get(key);
 558                 if (value instanceof Reference) {
 559                     proxyClass = (Class<?>) ((Reference) value).get();
 560                 }
 561                 if (proxyClass != null) {
 562                     // proxy class already generated: return it
 563                     return proxyClass;
 564                 } else if (value == pendingGenerationMarker) {
 565                     // proxy class being generated: wait for it
 566                     try {
 567                         cache.wait();
 568                     } catch (InterruptedException e) {
 569                         /*
 570                          * The class generation that we are waiting for should
 571                          * take a small, bounded time, so we can safely ignore
 572                          * thread interrupts here.
 573                          */
 574                     }
 575                     continue;
 576                 } else {
 577                     /*
 578                      * No proxy class for this list of interfaces has been
 579                      * generated or is being generated, so we will go and
 580                      * generate it now.  Mark it as pending generation.
 581                      */
 582                     cache.put(key, pendingGenerationMarker);
 583                     break;
 584                 }
 585             } while (true);
 586         }
 587 
 588         try {
 589             String proxyPkg = null;     // package to define proxy class in
 590 
 591             /*
 592              * Record the package of a non-public proxy interface so that the
 593              * proxy class will be defined in the same package.  Verify that
 594              * all non-public proxy interfaces are in the same package.
 595              */
 596             for (int i = 0; i < interfaces.length; i++) {
 597                 int flags = interfaces[i].getModifiers();
 598                 if (!Modifier.isPublic(flags)) {
 599                     String name = interfaces[i].getName();
 600                     int n = name.lastIndexOf('.');
 601                     String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
 602                     if (proxyPkg == null) {
 603                         proxyPkg = pkg;
 604                     } else if (!pkg.equals(proxyPkg)) {
 605                         throw new IllegalArgumentException(
 606                             "non-public interfaces from different packages");
 607                     }
 608                 }
 609             }
 610 
 611             if (proxyPkg == null) {
 612                 // if no non-public proxy interfaces, use sun.proxy package
 613                 proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
 614             }
 615 
 616             {
 617                 /*
 618                  * Choose a name for the proxy class to generate.
 619                  */
 620                 long num;
 621                 synchronized (nextUniqueNumberLock) {
 622                     num = nextUniqueNumber++;
 623                 }
 624                 String proxyName = proxyPkg + proxyClassNamePrefix + num;
 625                 /*
 626                  * Verify that the class loader hasn't already
 627                  * defined a class with the chosen name.
 628                  */
 629 
 630                 /*
 631                  * Generate the specified proxy class.
 632                  */
 633                 byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
 634                     proxyName, interfaces);
 635                 try {
 636                     proxyClass = defineClass0(loader, proxyName,
 637                         proxyClassFile, 0, proxyClassFile.length);
 638                 } catch (ClassFormatError e) {
 639                     /*
 640                      * A ClassFormatError here means that (barring bugs in the
 641                      * proxy class generation code) there was some other
 642                      * invalid aspect of the arguments supplied to the proxy
 643                      * class creation (such as virtual machine limitations
 644                      * exceeded).
 645                      */
 646                     throw new IllegalArgumentException(e.toString());
 647                 }
 648             }
 649             // add to set of all generated proxy classes, for isProxyClass
 650             proxyClasses.put(proxyClass, null);
 651 
 652         } finally {
 653             /*
 654              * We must clean up the "pending generation" state of the proxy
 655              * class cache entry somehow.  If a proxy class was successfully
 656              * generated, store it in the cache (with a weak reference);
 657              * otherwise, remove the reserved entry.  In all cases, notify
 658              * all waiters on reserved entries in this cache.
 659              */
 660             synchronized (cache) {
 661                 if (proxyClass != null) {
 662                     cache.put(key, new WeakReference<Class<?>>(proxyClass));
 663                 } else {
 664                     cache.remove(key);
 665                 }
 666                 cache.notifyAll();
 667             }
 668         }
 669         return proxyClass;
 670     }
 671 
 672     /**
 673      * Returns an instance of a proxy class for the specified interfaces
 674      * that dispatches method invocations to the specified invocation
 675      * handler.  This method is equivalent to:
 676      * <pre>
 677      *     Proxy.getProxyClass(loader, interfaces).
 678      *         getConstructor(new Class[] { InvocationHandler.class }).
 679      *         newInstance(new Object[] { handler });
 680      * </pre>
 681      *
 682      * <p>{@code Proxy.newProxyInstance} throws
 683      * {@code IllegalArgumentException} for the same reasons that
 684      * {@code Proxy.getProxyClass} does.
 685      *
 686      * @param   loader the class loader to define the proxy class
 687      * @param   interfaces the list of interfaces for the proxy class
 688      *          to implement
 689      * @param   h the invocation handler to dispatch method invocations to
 690      * @return  a proxy instance with the specified invocation handler of a
 691      *          proxy class that is defined by the specified class loader
 692      *          and that implements the specified interfaces
 693      * @throws  IllegalArgumentException if any of the restrictions on the
 694      *          parameters that may be passed to {@code getProxyClass}
 695      *          are violated
 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     public static Object newProxyInstance(ClassLoader loader,
 702                                           Class<?>[] interfaces,
 703                                           InvocationHandler h)
 704         throws IllegalArgumentException
 705     {
 706         if (h == null) {
 707             throw new NullPointerException();
 708         }
 709 
 710         /*
 711          * Look up or generate the designated proxy class.
 712          */
 713         Class<?> cl = getProxyClass0(loader, interfaces); // stack walk magic: do not refactor
 714 
 715         /*
 716          * Invoke its constructor with the designated invocation handler.
 717          */
 718         try {
 719             final Constructor<?> cons = cl.getConstructor(constructorParams);
 720             final InvocationHandler ih = h;
 721             SecurityManager sm = System.getSecurityManager();
 722             if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(cl)) {
 723                 // create proxy instance with doPrivilege as the proxy class may
 724                 // implement non-public interfaces that requires a special permission
 725                 return AccessController.doPrivileged(new PrivilegedAction<Object>() {
 726                     public Object run() {
 727                         return newInstance(cons, ih);
 728                     }
 729                 });
 730             } else {
 731                 return newInstance(cons, ih);
 732             }
 733         } catch (NoSuchMethodException e) {
 734             throw new InternalError(e.toString());
 735         }
 736     }
 737 
 738     private static Object newInstance(Constructor<?> cons, InvocationHandler h) {
 739         try {
 740             return cons.newInstance(new Object[] {h} );
 741         } catch (IllegalAccessException | InstantiationException e) {
 742             throw new InternalError(e.toString());
 743         } catch (InvocationTargetException e) {
 744             Throwable t = e.getCause();
 745             if (t instanceof RuntimeException) {
 746                 throw (RuntimeException) t;
 747             } else {
 748                 throw new InternalError(t.toString());
 749             }
 750         }
 751     }
 752 
 753     /**
 754      * Returns true if and only if the specified class was dynamically
 755      * generated to be a proxy class using the {@code getProxyClass}
 756      * method or the {@code newProxyInstance} method.
 757      *
 758      * <p>The reliability of this method is important for the ability
 759      * to use it to make security decisions, so its implementation should
 760      * not just test if the class in question extends {@code Proxy}.
 761      *
 762      * @param   cl the class to test
 763      * @return  {@code true} if the class is a proxy class and
 764      *          {@code false} otherwise
 765      * @throws  NullPointerException if {@code cl} is {@code null}
 766      */
 767     public static boolean isProxyClass(Class<?> cl) {
 768         if (cl == null) {
 769             throw new NullPointerException();
 770         }
 771 
 772         return proxyClasses.containsKey(cl);
 773     }
 774 
 775     /**
 776      * Returns the invocation handler for the specified proxy instance.
 777      *
 778      * @param   proxy the proxy instance to return the invocation handler for
 779      * @return  the invocation handler for the proxy instance
 780      * @throws  IllegalArgumentException if the argument is not a
 781      *          proxy instance
 782      */
 783     public static InvocationHandler getInvocationHandler(Object proxy)
 784         throws IllegalArgumentException
 785     {
 786         /*
 787          * Verify that the object is actually a proxy instance.
 788          */
 789         if (!isProxyClass(proxy.getClass())) {
 790             throw new IllegalArgumentException("not a proxy instance");
 791         }
 792 
 793         Proxy p = (Proxy) proxy;
 794         return p.h;
 795     }
 796 
 797     private static native Class defineClass0(ClassLoader loader, String name,
 798                                              byte[] b, int off, int len);
 799 }