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