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.security.AccessController; 29 import java.security.PrivilegedAction; 30 import java.util.Arrays; 31 import java.util.Collections; 32 import java.util.Deque; 33 import java.util.HashMap; 34 import java.util.HashSet; 35 import java.util.IdentityHashMap; 36 import java.util.LinkedList; 37 import java.util.List; 38 import java.util.Map; 39 import java.util.Objects; 40 import java.util.Set; 41 import java.util.concurrent.atomic.AtomicInteger; 42 import java.util.concurrent.atomic.AtomicLong; 43 import java.util.stream.Collectors; 44 import java.util.stream.Stream; 45 46 import jdk.internal.loader.BootLoader; 47 import jdk.internal.module.Modules; 48 import jdk.internal.misc.Unsafe; 49 import jdk.internal.misc.VM; 50 import sun.reflect.CallerSensitive; 51 import sun.reflect.Reflection; 52 import sun.reflect.misc.ReflectUtil; 53 import sun.security.util.SecurityConstants; 54 55 /** 56 * 57 * {@code Proxy} provides static methods for creating objects that act like instances 58 * of interfaces but allow for customized method invocation. 59 * To create a proxy instance for some interface {@code Foo}: 60 * <pre>{@code 61 * InvocationHandler handler = new MyInvocationHandler(...); 62 * Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(), 63 * new Class<?>[] { Foo.class }, 64 * handler); 65 * }</pre> 66 * 67 * <p> 68 * A <em>proxy class</em> is a class created at runtime that implements a specified 69 * list of interfaces, known as <em>proxy interfaces</em>. A <em>proxy instance</em> 70 * is an instance of a proxy class. 71 * 72 * Each proxy instance has an associated <i>invocation handler</i> 73 * object, which implements the interface {@link InvocationHandler}. 74 * A method invocation on a proxy instance through one of its proxy 75 * interfaces will be dispatched to the {@link InvocationHandler#invoke 76 * invoke} method of the instance's invocation handler, passing the proxy 77 * instance, a {@code java.lang.reflect.Method} object identifying 78 * the method that was invoked, and an array of type {@code Object} 79 * containing the arguments. The invocation handler processes the 80 * encoded method invocation as appropriate and the result that it 81 * returns will be returned as the result of the method invocation on 82 * the proxy instance. 83 * 84 * <p>A proxy class has the following properties: 85 * 86 * <ul> 87 * <li>The unqualified name of a proxy class is unspecified. The space 88 * of class names that begin with the string {@code "$Proxy"} 89 * should be, however, reserved for proxy classes. 90 * 91 * <li>The package and module in which a proxy class is defined is specified 92 * <a href="#membership">below</a>. 93 * 94 * <li>A proxy class is <em>final and non-abstract</em>. 95 * 96 * <li>A proxy class extends {@code java.lang.reflect.Proxy}. 97 * 98 * <li>A proxy class implements exactly the interfaces specified at its 99 * creation, in the same order. Invoking {@link Class#getInterfaces getInterfaces} 100 * on its {@code Class} object will return an array containing the same 101 * list of interfaces (in the order specified at its creation), invoking 102 * {@link Class#getMethods getMethods} on its {@code Class} object will return 103 * an array of {@code Method} objects that include all of the 104 * methods in those interfaces, and invoking {@code getMethod} will 105 * find methods in the proxy interfaces as would be expected. 106 * 107 * <li>The {@link java.security.ProtectionDomain} of a proxy class 108 * is the same as that of system classes loaded by the bootstrap class 109 * loader, such as {@code java.lang.Object}, because the code for a 110 * proxy class is generated by trusted system code. This protection 111 * domain will typically be granted {@code java.security.AllPermission}. 112 * 113 * <li>The {@link Proxy#isProxyClass Proxy.isProxyClass} method can be used 114 * to determine if a given class is a proxy class. 115 * </ul> 116 * 117 * <p>A proxy instance has the following properties: 118 * 119 * <ul> 120 * <li>Given a proxy instance {@code proxy} and one of the 121 * interfaces, {@code Foo}, implemented by its proxy class, the 122 * following expression will return true: 123 * <pre> 124 * {@code proxy instanceof Foo} 125 * </pre> 126 * and the following cast operation will succeed (rather than throwing 127 * a {@code ClassCastException}): 128 * <pre> 129 * {@code (Foo) proxy} 130 * </pre> 131 * 132 * <li>Each proxy instance has an associated invocation handler, the one 133 * that was passed to its constructor. The static 134 * {@link Proxy#getInvocationHandler Proxy.getInvocationHandler} method 135 * will return the invocation handler associated with the proxy instance 136 * passed as its argument. 137 * 138 * <li>An interface method invocation on a proxy instance will be 139 * encoded and dispatched to the invocation handler's {@link 140 * InvocationHandler#invoke invoke} method as described in the 141 * documentation for that method. 142 * 143 * <li>An invocation of the {@code hashCode}, 144 * {@code equals}, or {@code toString} methods declared in 145 * {@code java.lang.Object} on a proxy instance will be encoded and 146 * dispatched to the invocation handler's {@code invoke} method in 147 * the same manner as interface method invocations are encoded and 148 * dispatched, as described above. The declaring class of the 149 * {@code Method} object passed to {@code invoke} will be 150 * {@code java.lang.Object}. Other public methods of a proxy 151 * instance inherited from {@code java.lang.Object} are not 152 * overridden by a proxy class, so invocations of those methods behave 153 * like they do for instances of {@code java.lang.Object}. 154 * </ul> 155 * 156 * <h3><a name="membership">Package and Module Membership of Proxy Class</a></h3> 157 * 158 * The package and module to which a proxy class belongs are chosen such that 159 * the accessibility of the proxy class is in line with the accessibility of 160 * the proxy interfaces. Specifically, the package and the module membership 161 * of a proxy class defined via the 162 * {@link Proxy#getProxyClass(ClassLoader, Class[])} or 163 * {@link Proxy#newProxyInstance(ClassLoader, Class[], InvocationHandler)} 164 * methods is specified as follows: 165 * 166 * <ol> 167 * <li>If all the proxy interfaces are in <em>exported</em> packages: 168 * <ol type="a"> 169 * <li>if all the proxy interfaces are <em>public</em>, then the proxy class is 170 * <em>public</em> in a package exported by the 171 * {@linkplain ClassLoader#getUnnamedModule() unnamed module} of the specified 172 * loader. The name of the package is unspecified.</li> 173 * 174 * <li>if at least one of all the proxy interfaces is <em>non-public</em>, then 175 * the proxy class is <em>non-public</em> in the package and module of the 176 * non-public interfaces. All the non-public interfaces must be in the same 177 * package and module; otherwise, proxying them is 178 * <a href="#restrictions">not possible</a>.</li> 179 * </ol> 180 * </li> 181 * <li>If at least one proxy interface is a <em>non-exported</em> package: 182 * <ol type="a"> 183 * <li>if all the proxy interfaces are <em>public</em>, then the proxy class is 184 * <em>public</em> in a <em>non-exported</em> package of 185 * <a href="#dynamicmodule"><em>dynamic module</em>.</a> 186 * The names of the package and the module are unspecified.</li> 187 * 188 * <li>if at least one of all the proxy interfaces is <em>non-public</em>, then 189 * the proxy class is <em>non-public</em> in the package and module of the 190 * non-public interfaces. All the non-public interfaces must be in the same 191 * package and module; otherwise, proxying them is 192 * <a href="#restrictions">not possible</a>.</li> 193 * </ol> 194 * </li> 195 * </ol> 196 * 197 * <p> 198 * Note that if proxy interfaces with a mix of accessibilities -- 199 * exported public, exported non-public, non-exported public, non-exported non-public -- 200 * are proxied by the same instance, then the proxy class's accessibility is 201 * governed by the least accessible proxy interface. 202 * <p> 203 * Note that it is possible for arbitrary code to obtain access to a proxy class 204 * in an exported package with {@link AccessibleObject#setAccessible setAccessible}, 205 * whereas a proxy class in a non-exported package is never accessible to 206 * code outside the module of the proxy class. 207 * 208 * <p> 209 * Throughout this specification, a "non-exported package" refers to a package that 210 * is not exported to all modules. Specifically, it refers to a package that 211 * either is not exported at all by its containing module or is exported in a 212 * qualified fashion by its containing module. 213 * 214 * <h3><a name="dynamicmodule">Dynamic Modules</a></h3> 215 * <p> 216 * A dynamic module is a named module generated at runtime. A proxy class 217 * defined in a dynamic module is encapsulated and not accessible to any module. 218 * Calling {@link Constructor#newInstance(Object...)} on a proxy class in 219 * a dynamic module will throw {@code IllegalAccessException}; 220 * {@code Proxy.newProxyInstance} method should be used instead. 221 * 222 * <p> 223 * A dynamic module can read the modules of all of the superinterfaces of a proxy class 224 * and the modules of the types referenced by all public method signatures 225 * of a proxy class. If a superinterface or a referenced type, say {@code T}, 226 * is in a non-exported package, the {@linkplain java.lang.reflect.Module module} 227 * of {@code T} is updated to export the package of {@code T} to the dynamic module. 228 * 229 * <h3>Methods Duplicated in Multiple Proxy Interfaces</h3> 230 * 231 * <p>When two or more proxy interfaces contain a method with 232 * the same name and parameter signature, the order of the proxy class's 233 * interfaces becomes significant. When such a <i>duplicate method</i> 234 * is invoked on a proxy instance, the {@code Method} object passed 235 * to the invocation handler will not necessarily be the one whose 236 * declaring class is assignable from the reference type of the interface 237 * that the proxy's method was invoked through. This limitation exists 238 * because the corresponding method implementation in the generated proxy 239 * class cannot determine which interface it was invoked through. 240 * Therefore, when a duplicate method is invoked on a proxy instance, 241 * the {@code Method} object for the method in the foremost interface 242 * that contains the method (either directly or inherited through a 243 * superinterface) in the proxy class's list of interfaces is passed to 244 * the invocation handler's {@code invoke} method, regardless of the 245 * reference type through which the method invocation occurred. 246 * 247 * <p>If a proxy interface contains a method with the same name and 248 * parameter signature as the {@code hashCode}, {@code equals}, 249 * or {@code toString} methods of {@code java.lang.Object}, 250 * when such a method is invoked on a proxy instance, the 251 * {@code Method} object passed to the invocation handler will have 252 * {@code java.lang.Object} as its declaring class. In other words, 253 * the public, non-final methods of {@code java.lang.Object} 254 * logically precede all of the proxy interfaces for the determination of 255 * which {@code Method} object to pass to the invocation handler. 256 * 257 * <p>Note also that when a duplicate method is dispatched to an 258 * invocation handler, the {@code invoke} method may only throw 259 * checked exception types that are assignable to one of the exception 260 * types in the {@code throws} clause of the method in <i>all</i> of 261 * the proxy interfaces that it can be invoked through. If the 262 * {@code invoke} method throws a checked exception that is not 263 * assignable to any of the exception types declared by the method in one 264 * of the proxy interfaces that it can be invoked through, then an 265 * unchecked {@code UndeclaredThrowableException} will be thrown by 266 * the invocation on the proxy instance. This restriction means that not 267 * all of the exception types returned by invoking 268 * {@code getExceptionTypes} on the {@code Method} object 269 * passed to the {@code invoke} method can necessarily be thrown 270 * successfully by the {@code invoke} method. 271 * 272 * @author Peter Jones 273 * @see InvocationHandler 274 * @since 1.3 275 */ 276 public class Proxy implements java.io.Serializable { 277 private static final long serialVersionUID = -2222568056686623797L; 278 279 /** parameter types of a proxy class constructor */ 280 private static final Class<?>[] constructorParams = 281 { InvocationHandler.class }; 282 283 /** 284 * a cache of proxy constructors with 285 * {@link Constructor#setAccessible(boolean) accessible} flag already set 286 */ 287 private static final ClassLoaderValue<Constructor<?>> proxyCache = 288 new ClassLoaderValue<>(); 289 290 /** 291 * the invocation handler for this proxy instance. 292 * @serial 293 */ 294 protected InvocationHandler h; 295 296 /** 297 * Prohibits instantiation. 298 */ 299 private Proxy() { 300 } 301 302 /** 303 * Constructs a new {@code Proxy} instance from a subclass 304 * (typically, a dynamic proxy class) with the specified value 305 * for its invocation handler. 306 * 307 * @param h the invocation handler for this proxy instance 308 * 309 * @throws NullPointerException if the given invocation handler, {@code h}, 310 * is {@code null}. 311 */ 312 protected Proxy(InvocationHandler h) { 313 Objects.requireNonNull(h); 314 this.h = h; 315 } 316 317 /** 318 * Returns the {@code java.lang.Class} object for a proxy class 319 * given a class loader and an array of interfaces. The proxy class 320 * will be defined by the specified class loader and will implement 321 * all of the supplied interfaces. If any of the given interfaces 322 * is non-public, the proxy class will be non-public. If a proxy class 323 * for the same permutation of interfaces has already been defined by the 324 * class loader, then the existing proxy class will be returned; otherwise, 325 * a proxy class for those interfaces will be generated dynamically 326 * and defined by the class loader. 327 * 328 * @param loader the class loader to define the proxy class 329 * @param interfaces the list of interfaces for the proxy class 330 * to implement 331 * @return a proxy class that is defined in the specified class loader 332 * and that implements the specified interfaces 333 * @throws IllegalArgumentException if any of the <a href="#restrictions"> 334 * restrictions</a> on the parameters are violated 335 * @throws SecurityException if a security manager, <em>s</em>, is present 336 * and any of the following conditions is met: 337 * <ul> 338 * <li> the given {@code loader} is {@code null} and 339 * the caller's class loader is not {@code null} and the 340 * invocation of {@link SecurityManager#checkPermission 341 * s.checkPermission} with 342 * {@code RuntimePermission("getClassLoader")} permission 343 * denies access.</li> 344 * <li> for each proxy interface, {@code intf}, 345 * the caller's class loader is not the same as or an 346 * ancestor of the class loader for {@code intf} and 347 * invocation of {@link SecurityManager#checkPackageAccess 348 * s.checkPackageAccess()} denies access to {@code intf}.</li> 349 * </ul> 350 * @throws NullPointerException if the {@code interfaces} array 351 * argument or any of its elements are {@code null} 352 * 353 * @deprecated Proxy classes generated in a named module are encapsulated and not 354 * accessible to code outside its module. 355 * {@link Constructor#newInstance(Object...) Constructor.newInstance} will throw 356 * {@code IllegalAccessException} when it is called on an inaccessible proxy class. 357 * Use {@link #newProxyInstance(ClassLoader, Class[], InvocationHandler)} 358 * to create a proxy instance instead. 359 * 360 * @see <a href="#membership">Package and Module Membership of Proxy Class</a> 361 */ 362 @Deprecated 363 @CallerSensitive 364 public static Class<?> getProxyClass(ClassLoader loader, 365 Class<?>... interfaces) 366 throws IllegalArgumentException 367 { 368 Class<?> caller = System.getSecurityManager() == null 369 ? null 370 : Reflection.getCallerClass(); 371 372 return getProxyConstructor(caller, loader, interfaces) 373 .getDeclaringClass(); 374 } 375 376 /** 377 * Returns the {@code Constructor} object of a proxy class that takes a 378 * single argument of type {@link InvocationHandler}, given a class loader 379 * and an array of interfaces. The returned constructor will have the 380 * {@link Constructor#setAccessible(boolean) accessible} flag already set. 381 * 382 * @param caller passed from a public-facing @CallerSensitive method if 383 * SecurityManager is set or {@code null} if there's no 384 * SecurityManager 385 * @param loader the class loader to define the proxy class 386 * @param interfaces the list of interfaces for the proxy class 387 * to implement 388 * @return a Constructor of the proxy class taking single 389 * {@code InvocationHandler} parameter 390 */ 391 private static Constructor<?> getProxyConstructor(Class<?> caller, 392 ClassLoader loader, 393 Class<?>... interfaces) 394 { 395 // optimization for single interface 396 if (interfaces.length == 1) { 397 Class<?> intf = interfaces[0]; 398 if (caller != null) { 399 checkProxyAccess(caller, loader, intf); 400 } 401 return proxyCache.sub(intf).computeIfAbsent( 402 loader, 403 (ld, clv) -> new ProxyBuilder(ld, clv.key()).build() 404 ); 405 } else { 406 // interfaces cloned 407 final Class<?>[] intfsArray = interfaces.clone(); 408 if (caller != null) { 409 checkProxyAccess(caller, loader, intfsArray); 410 } 411 final List<Class<?>> intfs = Arrays.asList(intfsArray); 412 return proxyCache.sub(intfs).computeIfAbsent( 413 loader, 414 (ld, clv) -> new ProxyBuilder(ld, clv.key()).build() 415 ); 416 } 417 } 418 419 /* 420 * Check permissions required to create a Proxy class. 421 * 422 * To define a proxy class, it performs the access checks as in 423 * Class.forName (VM will invoke ClassLoader.checkPackageAccess): 424 * 1. "getClassLoader" permission check if loader == null 425 * 2. checkPackageAccess on the interfaces it implements 426 * 427 * To get a constructor and new instance of a proxy class, it performs 428 * the package access check on the interfaces it implements 429 * as in Class.getConstructor. 430 * 431 * If an interface is non-public, the proxy class must be defined by 432 * the defining loader of the interface. If the caller's class loader 433 * is not the same as the defining loader of the interface, the VM 434 * will throw IllegalAccessError when the generated proxy class is 435 * being defined. 436 */ 437 private static void checkProxyAccess(Class<?> caller, 438 ClassLoader loader, 439 Class<?> ... interfaces) 440 { 441 SecurityManager sm = System.getSecurityManager(); 442 if (sm != null) { 443 ClassLoader ccl = caller.getClassLoader(); 444 if (VM.isSystemDomainLoader(loader) && !VM.isSystemDomainLoader(ccl)) { 445 sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); 446 } 447 ReflectUtil.checkProxyPackageAccess(ccl, interfaces); 448 } 449 } 450 451 /** 452 * Builder for a proxy class. 453 * 454 * If the module is not specified in this ProxyBuilder constructor, 455 * it will map from the given loader and interfaces to the module 456 * in which the proxy class will be defined. 457 */ 458 private static final class ProxyBuilder { 459 private static final Unsafe UNSAFE = Unsafe.getUnsafe(); 460 461 // prefix for all proxy class names 462 private static final String proxyClassNamePrefix = "$Proxy"; 463 464 // next number to use for generation of unique proxy class names 465 private static final AtomicLong nextUniqueNumber = new AtomicLong(); 466 467 // a reverse cache of defined proxy classes 468 private static final ClassLoaderValue<Boolean> reverseProxyCache = 469 new ClassLoaderValue<>(); 470 471 private static Class<?> defineProxyClass(Module m, List<Class<?>> interfaces) { 472 String proxyPkg = null; // package to define proxy class in 473 int accessFlags = Modifier.PUBLIC | Modifier.FINAL; 474 475 /* 476 * Record the package of a non-public proxy interface so that the 477 * proxy class will be defined in the same package. Verify that 478 * all non-public proxy interfaces are in the same package. 479 */ 480 for (Class<?> intf : interfaces) { 481 int flags = intf.getModifiers(); 482 if (!Modifier.isPublic(flags)) { 483 accessFlags = Modifier.FINAL; // non-public, final 484 String pkg = intf.getPackageName(); 485 if (proxyPkg == null) { 486 proxyPkg = pkg; 487 } else if (!pkg.equals(proxyPkg)) { 488 throw new IllegalArgumentException( 489 "non-public interfaces from different packages"); 490 } 491 } 492 } 493 494 if (proxyPkg == null) { 495 // all proxy interfaces are public 496 proxyPkg = m.isNamed() ? PROXY_PACKAGE_PREFIX + "." + m.getName() 497 : PROXY_PACKAGE_PREFIX; 498 } else if (proxyPkg.isEmpty() && m.isNamed()) { 499 throw new IllegalArgumentException( 500 "Unnamed package cannot be added to " + m); 501 } 502 503 // add the package to the runtime module if not exists 504 if (m.isNamed()) { 505 m.addPackage(proxyPkg); 506 } 507 508 /* 509 * Choose a name for the proxy class to generate. 510 */ 511 long num = nextUniqueNumber.getAndIncrement(); 512 String proxyName = proxyPkg.isEmpty() ? proxyClassNamePrefix + num 513 : proxyPkg + "." + proxyClassNamePrefix + num; 514 515 ClassLoader loader = getLoader(m); 516 trace(proxyName, m, loader, interfaces); 517 518 /* 519 * Generate the specified proxy class. 520 */ 521 byte[] proxyClassFile = ProxyGenerator.generateProxyClass( 522 proxyName, interfaces.toArray(EMPTY_CLASS_ARRAY), accessFlags); 523 try { 524 Class<?> pc = UNSAFE.defineClass(proxyName, proxyClassFile, 525 0, proxyClassFile.length, 526 loader, null); 527 reverseProxyCache.sub(pc).putIfAbsent(loader, Boolean.TRUE); 528 return pc; 529 } catch (ClassFormatError e) { 530 /* 531 * A ClassFormatError here means that (barring bugs in the 532 * proxy class generation code) there was some other 533 * invalid aspect of the arguments supplied to the proxy 534 * class creation (such as virtual machine limitations 535 * exceeded). 536 */ 537 throw new IllegalArgumentException(e.toString()); 538 } 539 } 540 541 /** 542 * Test if given class is a class defined by 543 * {@link #defineProxyClass(Module, List)} 544 */ 545 static boolean isProxyClass(Class<?> c) { 546 return Objects.equals(reverseProxyCache.sub(c).get(c.getClassLoader()), 547 Boolean.TRUE); 548 } 549 550 private static boolean isExportedType(Class<?> c) { 551 String pn = c.getPackageName(); 552 return Modifier.isPublic(c.getModifiers()) && c.getModule().isExported(pn); 553 } 554 555 private static boolean isPackagePrivateType(Class<?> c) { 556 return !Modifier.isPublic(c.getModifiers()); 557 } 558 559 private static String toDetails(Class<?> c) { 560 String access = "unknown"; 561 if (isExportedType(c)) { 562 access = "exported"; 563 } else if (isPackagePrivateType(c)) { 564 access = "package-private"; 565 } else { 566 access = "module-private"; 567 } 568 ClassLoader ld = c.getClassLoader(); 569 return String.format(" %s/%s %s loader %s", 570 c.getModule().getName(), c.getName(), access, ld); 571 } 572 573 static void trace(String cn, Module module, ClassLoader loader, List<Class<?>> interfaces) { 574 if (isDebug()) { 575 System.out.format("PROXY: %s/%s defined by %s%n", module.getName(), cn, loader); 576 } 577 if (isDebug("debug")) { 578 interfaces.stream() 579 .forEach(c -> System.out.println(toDetails(c))); 580 } 581 } 582 583 private static final String DEBUG = 584 AccessController.doPrivileged(new PrivilegedAction<>() { 585 public String run() { 586 return System.getProperty("jdk.proxy.debug", ""); 587 } 588 }); 589 590 private static boolean isDebug() { 591 return !DEBUG.isEmpty(); 592 } 593 private static boolean isDebug(String flag) { 594 return DEBUG.equals(flag); 595 } 596 597 // ProxyBuilder instance members start here.... 598 599 private final ClassLoader loader; 600 private final List<Class<?>> interfaces; 601 private final Module module; 602 ProxyBuilder(ClassLoader loader, List<Class<?>> interfaces) { 603 if (!VM.isModuleSystemInited()) { 604 throw new InternalError("Proxy is not supported until module system is fully initialzed"); 605 } 606 if (interfaces.size() > 65535) { 607 throw new IllegalArgumentException("interface limit exceeded"); 608 } 609 610 Set<Class<?>> refTypes = referencedTypes(loader, interfaces); 611 612 // IAE if violates any restrictions specified in newProxyInstance 613 validateProxyInterfaces(loader, interfaces, refTypes); 614 615 this.loader = loader; 616 this.interfaces = interfaces; 617 this.module = mapToModule(loader, interfaces, refTypes); 618 assert getLoader(module) == loader; 619 } 620 621 ProxyBuilder(ClassLoader loader, Class<?> intf) { 622 this(loader, Collections.singletonList(intf)); 623 } 624 625 /** 626 * Generate a proxy class and return its proxy Constructor with 627 * accessible flag already set. If the target module does not have access 628 * to any interface types, IllegalAccessError will be thrown by the VM 629 * at defineClass time. 630 * 631 * Must call the checkProxyAccess method to perform permission checks 632 * before calling this. 633 */ 634 Constructor<?> build() { 635 Class<?> proxyClass = defineProxyClass(module, interfaces); 636 final Constructor<?> cons; 637 try { 638 cons = proxyClass.getConstructor(constructorParams); 639 } catch (NoSuchMethodException e) { 640 throw new InternalError(e.toString(), e); 641 } 642 AccessController.doPrivileged(new PrivilegedAction<Void>() { 643 public Void run() { 644 cons.setAccessible(true); 645 return null; 646 } 647 }); 648 return cons; 649 } 650 651 /** 652 * Validate the given proxy interfaces and the given referenced types 653 * are visible to the defining loader. 654 * 655 * @throws IllegalArgumentException if it violates the restrictions specified 656 * in {@link Proxy#newProxyInstance} 657 */ 658 private static void validateProxyInterfaces(ClassLoader loader, 659 List<Class<?>> interfaces, 660 Set<Class<?>> refTypes) 661 { 662 Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.size()); 663 for (Class<?> intf : interfaces) { 664 /* 665 * Verify that the class loader resolves the name of this 666 * interface to the same Class object. 667 */ 668 ensureVisible(loader, intf); 669 670 /* 671 * Verify that the Class object actually represents an 672 * interface. 673 */ 674 if (!intf.isInterface()) { 675 throw new IllegalArgumentException(intf.getName() + " is not an interface"); 676 } 677 678 /* 679 * Verify that this interface is not a duplicate. 680 */ 681 if (interfaceSet.put(intf, Boolean.TRUE) != null) { 682 throw new IllegalArgumentException("repeated interface: " + intf.getName()); 683 } 684 } 685 686 for (Class<?> type : refTypes) { 687 ensureVisible(loader, type); 688 } 689 } 690 691 /* 692 * Returns all types referenced by all public method signatures of 693 * the proxy interfaces 694 */ 695 private static Set<Class<?>> referencedTypes(ClassLoader loader, 696 List<Class<?>> interfaces) { 697 return interfaces.stream() 698 .flatMap(intf -> Stream.of(intf.getMethods()) 699 .flatMap(ProxyBuilder::methodRefTypes) 700 .map(ProxyBuilder::getElementType) 701 .filter(t -> !t.isPrimitive())) 702 .collect(Collectors.toSet()); 703 } 704 705 /* 706 * Extracts all types referenced on a method signature including 707 * its return type, parameter types, and exception types. 708 */ 709 private static Stream<Class<?>> methodRefTypes(Method m) { 710 return Stream.of(new Class<?>[] { m.getReturnType() }, 711 m.getParameterTypes(), 712 m.getExceptionTypes()) 713 .flatMap(Stream::of); 714 } 715 716 /** 717 * Returns the module that the generated proxy class belongs to. 718 * 719 * If all proxy interfaces are public and in exported packages, 720 * then the proxy class is in unnamed module. 721 * 722 * If any of proxy interface is package-private, then the proxy class 723 * is in the same module of the package-private interface. 724 * 725 * If all proxy interfaces are public and at least one in a non-exported 726 * package, then the proxy class is in a dynamic module in a non-exported 727 * package. Reads edge and qualified exports are added for 728 * dynamic module to access. 729 */ 730 private static Module mapToModule(ClassLoader loader, 731 List<Class<?>> interfaces, 732 Set<Class<?>> refTypes) { 733 Map<Class<?>, Module> modulePrivateTypes = new HashMap<>(); 734 Map<Class<?>, Module> packagePrivateTypes = new HashMap<>(); 735 for (Class<?> intf : interfaces) { 736 Module m = intf.getModule(); 737 if (Modifier.isPublic(intf.getModifiers())) { 738 // module-private types 739 if (!m.isExported(intf.getPackageName())) { 740 modulePrivateTypes.put(intf, m); 741 } 742 } else { 743 packagePrivateTypes.put(intf, m); 744 } 745 } 746 747 // all proxy interfaces are public and exported, the proxy class is in unnamed module 748 // Such proxy class is accessible to any unnamed module and named module that 749 // can read unnamed module 750 if (packagePrivateTypes.isEmpty() && modulePrivateTypes.isEmpty()) { 751 return loader != null ? loader.getUnnamedModule() : BootLoader.getUnnamedModule(); 752 } 753 754 if (packagePrivateTypes.size() > 0) { 755 // all package-private types must be in the same runtime package 756 // i.e. same package name and same module (named or unnamed) 757 // 758 // Configuration will fail if M1 and in M2 defined by the same loader 759 // and both have the same package p (so no need to check class loader) 760 if (packagePrivateTypes.size() > 1 && 761 (packagePrivateTypes.keySet().stream() // more than one package 762 .map(Class::getPackageName).distinct().count() > 1 || 763 packagePrivateTypes.values().stream() // or more than one module 764 .distinct().count() > 1)) { 765 throw new IllegalArgumentException( 766 "non-public interfaces from different packages"); 767 } 768 769 // all package-private types are in the same module (named or unnamed) 770 Module target = null; 771 for (Module m : packagePrivateTypes.values()) { 772 if (getLoader(m) != loader) { 773 // the specified loader is not the same class loader of the non-public interface 774 throw new IllegalArgumentException( 775 "non-public interface is not defined by the given loader"); 776 } 777 target = m; 778 } 779 780 // validate if the target module can access all other interfaces 781 for (Class<?> intf : interfaces) { 782 Module m = intf.getModule(); 783 if (m == target) continue; 784 785 if (!target.canRead(m) || !m.isExported(intf.getPackageName(), target)) { 786 throw new IllegalArgumentException(target + " can't access " + intf.getName()); 787 } 788 } 789 790 // return the module of the package-private interface 791 return target; 792 } 793 794 // all proxy interfaces are public and at least one in a non-exported package 795 // map to dynamic proxy module and add reads edge and qualified exports, if necessary 796 Module target = getDynamicModule(loader); 797 798 // set up proxy class access to proxy interfaces and superinterfaces 799 Deque<Class<?>> deque = new LinkedList<>(interfaces); 800 Set<Class<?>> visited = new HashSet<>(); 801 while (!deque.isEmpty()) { 802 Class<?> c = deque.poll(); 803 if (!visited.add(c)) { 804 continue; 805 } 806 ensureAccess(target, c); 807 808 // add all superinterfaces 809 for (Class<?> intf : c.getInterfaces()) { 810 deque.add(intf); 811 } 812 } 813 814 // set up proxy class access to types referenced in the method signature 815 refTypes.stream() 816 .filter(t -> !visited.contains(t)) 817 .forEach(t -> ensureAccess(target, t)); 818 return target; 819 } 820 821 /* 822 * Ensure the given module can access the given class. 823 */ 824 private static void ensureAccess(Module target, Class<?> c) { 825 Module m = c.getModule(); 826 // add read edge and qualified export for the target module to access 827 if (!target.canRead(m)) { 828 Modules.addReads(target, m); 829 } 830 String pn = c.getPackageName(); 831 if (!m.isExported(pn, target)) { 832 Modules.addExports(m, pn, target); 833 } 834 } 835 836 /* 837 * Ensure the given class is visible to the class loader. 838 */ 839 private static void ensureVisible(ClassLoader ld, Class<?> c) { 840 Class<?> type = null; 841 try { 842 type = Class.forName(c.getName(), false, ld); 843 } catch (ClassNotFoundException e) { 844 } 845 if (type != c) { 846 throw new IllegalArgumentException(c.getName() + 847 " referenced from a method is not visible from class loader"); 848 } 849 } 850 851 private static Class<?> getElementType(Class<?> type) { 852 Class<?> e = type; 853 while (e.isArray()) { 854 e = e.getComponentType(); 855 } 856 return e; 857 } 858 859 private static final ClassLoaderValue<Module> dynProxyModules = 860 new ClassLoaderValue<>(); 861 private static final AtomicInteger counter = new AtomicInteger(); 862 863 /* 864 * Define a dynamic module for the generated proxy classes in a non-exported package 865 * named com.sun.proxy.$MODULE. 866 * 867 * Each class loader will have one dynamic module. 868 */ 869 private static Module getDynamicModule(ClassLoader loader) { 870 return dynProxyModules.computeIfAbsent(loader, (ld, clv) -> { 871 // create a dynamic module and setup module access 872 String mn = "jdk.proxy" + counter.incrementAndGet(); 873 String pn = PROXY_PACKAGE_PREFIX + "." + mn; 874 Module m = Modules.defineModule(ld, mn, Collections.singleton(pn)); 875 Modules.addReads(m, Proxy.class.getModule()); 876 // java.base to create proxy instance 877 Modules.addExports(m, pn, Object.class.getModule()); 878 return m; 879 }); 880 } 881 } 882 883 /** 884 * Returns a proxy instance for the specified interfaces 885 * that dispatches method invocations to the specified invocation 886 * handler. 887 * <p> 888 * <a name="restrictions">{@code IllegalArgumentException} will be thrown 889 * if any of the following restrictions is violated:</a> 890 * <ul> 891 * <li>All of {@code Class} objects in the given {@code interfaces} array 892 * must represent interfaces, not classes or primitive types. 893 * 894 * <li>No two elements in the {@code interfaces} array may 895 * refer to identical {@code Class} objects. 896 * 897 * <li>All of the interface types must be visible by name through the 898 * specified class loader. In other words, for class loader 899 * {@code cl} and every interface {@code i}, the following 900 * expression must be true:<p> 901 * {@code Class.forName(i.getName(), false, cl) == i} 902 * 903 * <li>All of the types referenced by all 904 * public method signatures of the specified interfaces 905 * and those inherited by their superinterfaces 906 * must be visible by name through the specified class loader. 907 * 908 * <li>All non-public interfaces must be in the same package 909 * and module, defined by the specified class loader and 910 * the module of the non-public interfaces can access all of 911 * the interface types; otherwise, it would not be possible for 912 * the proxy class to implement all of the interfaces, 913 * regardless of what package it is defined in. 914 * 915 * <li>For any set of member methods of the specified interfaces 916 * that have the same signature: 917 * <ul> 918 * <li>If the return type of any of the methods is a primitive 919 * type or void, then all of the methods must have that same 920 * return type. 921 * <li>Otherwise, one of the methods must have a return type that 922 * is assignable to all of the return types of the rest of the 923 * methods. 924 * </ul> 925 * 926 * <li>The resulting proxy class must not exceed any limits imposed 927 * on classes by the virtual machine. For example, the VM may limit 928 * the number of interfaces that a class may implement to 65535; in 929 * that case, the size of the {@code interfaces} array must not 930 * exceed 65535. 931 * </ul> 932 * 933 * <p>Note that the order of the specified proxy interfaces is 934 * significant: two requests for a proxy class with the same combination 935 * of interfaces but in a different order will result in two distinct 936 * proxy classes. 937 * 938 * @param loader the class loader to define the proxy class 939 * @param interfaces the list of interfaces for the proxy class 940 * to implement 941 * @param h the invocation handler to dispatch method invocations to 942 * @return a proxy instance with the specified invocation handler of a 943 * proxy class that is defined by the specified class loader 944 * and that implements the specified interfaces 945 * @throws IllegalArgumentException if any of the <a href="#restrictions"> 946 * restrictions</a> on the parameters are violated 947 * @throws SecurityException if a security manager, <em>s</em>, is present 948 * and any of the following conditions is met: 949 * <ul> 950 * <li> the given {@code loader} is {@code null} and 951 * the caller's class loader is not {@code null} and the 952 * invocation of {@link SecurityManager#checkPermission 953 * s.checkPermission} with 954 * {@code RuntimePermission("getClassLoader")} permission 955 * denies access;</li> 956 * <li> for each proxy interface, {@code intf}, 957 * the caller's class loader is not the same as or an 958 * ancestor of the class loader for {@code intf} and 959 * invocation of {@link SecurityManager#checkPackageAccess 960 * s.checkPackageAccess()} denies access to {@code intf};</li> 961 * <li> any of the given proxy interfaces is non-public and the 962 * caller class is not in the same {@linkplain Package runtime package} 963 * as the non-public interface and the invocation of 964 * {@link SecurityManager#checkPermission s.checkPermission} with 965 * {@code ReflectPermission("newProxyInPackage.{package name}")} 966 * permission denies access.</li> 967 * </ul> 968 * @throws NullPointerException if the {@code interfaces} array 969 * argument or any of its elements are {@code null}, or 970 * if the invocation handler, {@code h}, is 971 * {@code null} 972 * 973 * @see <a href="#membership">Package and Module Membership of Proxy Class</a> 974 */ 975 @CallerSensitive 976 public static Object newProxyInstance(ClassLoader loader, 977 Class<?>[] interfaces, 978 InvocationHandler h) { 979 Objects.requireNonNull(h); 980 981 final Class<?> caller = System.getSecurityManager() == null 982 ? null 983 : Reflection.getCallerClass(); 984 985 /* 986 * Look up or generate the designated proxy class and its constructor. 987 */ 988 Constructor<?> cons = getProxyConstructor(caller, loader, interfaces); 989 990 return newProxyInstance(caller, cons, h); 991 } 992 993 private static Object newProxyInstance(Class<?> caller, // null if no SecurityManager 994 Constructor<?> cons, 995 InvocationHandler h) { 996 /* 997 * Invoke its constructor with the designated invocation handler. 998 */ 999 try { 1000 if (caller != null) { 1001 checkNewProxyPermission(caller, cons.getDeclaringClass()); 1002 } 1003 1004 return cons.newInstance(new Object[]{h}); 1005 } catch (IllegalAccessException | InstantiationException e) { 1006 throw new InternalError(e.toString(), e); 1007 } catch (InvocationTargetException e) { 1008 Throwable t = e.getCause(); 1009 if (t instanceof RuntimeException) { 1010 throw (RuntimeException) t; 1011 } else { 1012 throw new InternalError(t.toString(), t); 1013 } 1014 } 1015 } 1016 1017 private static void checkNewProxyPermission(Class<?> caller, Class<?> proxyClass) { 1018 SecurityManager sm = System.getSecurityManager(); 1019 if (sm != null) { 1020 if (ReflectUtil.isNonPublicProxyClass(proxyClass)) { 1021 ClassLoader ccl = caller.getClassLoader(); 1022 ClassLoader pcl = proxyClass.getClassLoader(); 1023 1024 // do permission check if the caller is in a different runtime package 1025 // of the proxy class 1026 int n = proxyClass.getName().lastIndexOf('.'); 1027 String pkg = (n == -1) ? "" : proxyClass.getName().substring(0, n); 1028 1029 n = caller.getName().lastIndexOf('.'); 1030 String callerPkg = (n == -1) ? "" : caller.getName().substring(0, n); 1031 1032 if (pcl != ccl || !pkg.equals(callerPkg)) { 1033 sm.checkPermission(new ReflectPermission("newProxyInPackage." + pkg)); 1034 } 1035 } 1036 } 1037 } 1038 1039 /** 1040 * Returns the class loader for the given module. 1041 */ 1042 private static ClassLoader getLoader(Module m) { 1043 PrivilegedAction<ClassLoader> pa = m::getClassLoader; 1044 return AccessController.doPrivileged(pa); 1045 } 1046 1047 /** 1048 * Returns true if the given class is a proxy class. 1049 * 1050 * @implNote The reliability of this method is important for the ability 1051 * to use it to make security decisions, so its implementation should 1052 * not just test if the class in question extends {@code Proxy}. 1053 * 1054 * @param cl the class to test 1055 * @return {@code true} if the class is a proxy class and 1056 * {@code false} otherwise 1057 * @throws NullPointerException if {@code cl} is {@code null} 1058 */ 1059 public static boolean isProxyClass(Class<?> cl) { 1060 return Proxy.class.isAssignableFrom(cl) && ProxyBuilder.isProxyClass(cl); 1061 } 1062 1063 /** 1064 * Returns the invocation handler for the specified proxy instance. 1065 * 1066 * @param proxy the proxy instance to return the invocation handler for 1067 * @return the invocation handler for the proxy instance 1068 * @throws IllegalArgumentException if the argument is not a 1069 * proxy instance 1070 * @throws SecurityException if a security manager, <em>s</em>, is present 1071 * and the caller's class loader is not the same as or an 1072 * ancestor of the class loader for the invocation handler 1073 * and invocation of {@link SecurityManager#checkPackageAccess 1074 * s.checkPackageAccess()} denies access to the invocation 1075 * handler's class. 1076 */ 1077 @CallerSensitive 1078 public static InvocationHandler getInvocationHandler(Object proxy) 1079 throws IllegalArgumentException 1080 { 1081 /* 1082 * Verify that the object is actually a proxy instance. 1083 */ 1084 if (!isProxyClass(proxy.getClass())) { 1085 throw new IllegalArgumentException("not a proxy instance"); 1086 } 1087 1088 final Proxy p = (Proxy) proxy; 1089 final InvocationHandler ih = p.h; 1090 if (System.getSecurityManager() != null) { 1091 Class<?> ihClass = ih.getClass(); 1092 Class<?> caller = Reflection.getCallerClass(); 1093 if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(), 1094 ihClass.getClassLoader())) 1095 { 1096 ReflectUtil.checkPackageAccess(ihClass); 1097 } 1098 } 1099 1100 return ih; 1101 } 1102 1103 private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[0]; 1104 private static final String PROXY_PACKAGE_PREFIX = ReflectUtil.PROXY_PACKAGE; 1105 }