1 /* 2 * Copyright (c) 2001, 2017, 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 jdk.internal.reflect; 27 28 import java.io.Externalizable; 29 import java.io.ObjectInputStream; 30 import java.io.ObjectOutputStream; 31 import java.io.ObjectStreamClass; 32 import java.io.OptionalDataException; 33 import java.io.Serializable; 34 import java.lang.invoke.MethodHandle; 35 import java.lang.invoke.MethodHandles; 36 import java.lang.reflect.Field; 37 import java.lang.reflect.Executable; 38 import java.lang.reflect.InvocationTargetException; 39 import java.lang.reflect.Method; 40 import java.lang.reflect.Constructor; 41 import java.lang.reflect.Modifier; 42 import java.security.Permission; 43 import java.security.PrivilegedAction; 44 import java.util.Objects; 45 import java.util.Properties; 46 47 import jdk.internal.misc.VM; 48 import sun.reflect.misc.ReflectUtil; 49 import sun.security.action.GetPropertyAction; 50 51 /** <P> The master factory for all reflective objects, both those in 52 java.lang.reflect (Fields, Methods, Constructors) as well as their 53 delegates (FieldAccessors, MethodAccessors, ConstructorAccessors). 54 </P> 55 56 <P> The methods in this class are extremely unsafe and can cause 57 subversion of both the language and the verifier. For this reason, 58 they are all instance methods, and access to the constructor of 59 this factory is guarded by a security check, in similar style to 60 {@link jdk.internal.misc.Unsafe}. </P> 61 */ 62 63 public class ReflectionFactory { 64 65 private static boolean initted = false; 66 private static final Permission reflectionFactoryAccessPerm 67 = new RuntimePermission("reflectionFactoryAccess"); 68 private static final ReflectionFactory soleInstance = new ReflectionFactory(); 69 // Provides access to package-private mechanisms in java.lang.reflect 70 private static volatile LangReflectAccess langReflectAccess; 71 72 /* Method for static class initializer <clinit>, or null */ 73 private static volatile Method hasStaticInitializerMethod; 74 75 // 76 // "Inflation" mechanism. Loading bytecodes to implement 77 // Method.invoke() and Constructor.newInstance() currently costs 78 // 3-4x more than an invocation via native code for the first 79 // invocation (though subsequent invocations have been benchmarked 80 // to be over 20x faster). Unfortunately this cost increases 81 // startup time for certain applications that use reflection 82 // intensively (but only once per class) to bootstrap themselves. 83 // To avoid this penalty we reuse the existing JVM entry points 84 // for the first few invocations of Methods and Constructors and 85 // then switch to the bytecode-based implementations. 86 // 87 // Package-private to be accessible to NativeMethodAccessorImpl 88 // and NativeConstructorAccessorImpl 89 private static boolean noInflation = false; 90 private static int inflationThreshold = 15; 91 92 private ReflectionFactory() { 93 } 94 95 /** 96 * A convenience class for acquiring the capability to instantiate 97 * reflective objects. Use this instead of a raw call to {@link 98 * #getReflectionFactory} in order to avoid being limited by the 99 * permissions of your callers. 100 * 101 * <p>An instance of this class can be used as the argument of 102 * <code>AccessController.doPrivileged</code>. 103 */ 104 public static final class GetReflectionFactoryAction 105 implements PrivilegedAction<ReflectionFactory> { 106 public ReflectionFactory run() { 107 return getReflectionFactory(); 108 } 109 } 110 111 /** 112 * Provides the caller with the capability to instantiate reflective 113 * objects. 114 * 115 * <p> First, if there is a security manager, its 116 * <code>checkPermission</code> method is called with a {@link 117 * java.lang.RuntimePermission} with target 118 * <code>"reflectionFactoryAccess"</code>. This may result in a 119 * security exception. 120 * 121 * <p> The returned <code>ReflectionFactory</code> object should be 122 * carefully guarded by the caller, since it can be used to read and 123 * write private data and invoke private methods, as well as to load 124 * unverified bytecodes. It must never be passed to untrusted code. 125 * 126 * @exception SecurityException if a security manager exists and its 127 * <code>checkPermission</code> method doesn't allow 128 * access to the RuntimePermission "reflectionFactoryAccess". */ 129 public static ReflectionFactory getReflectionFactory() { 130 SecurityManager security = System.getSecurityManager(); 131 if (security != null) { 132 // TO DO: security.checkReflectionFactoryAccess(); 133 security.checkPermission(reflectionFactoryAccessPerm); 134 } 135 return soleInstance; 136 } 137 138 /** 139 * Returns an alternate reflective Method instance for the given method 140 * intended for reflection to invoke, if present. 141 * 142 * A trusted method can define an alternate implementation for a method `foo` 143 * by defining a method named "reflected$foo" that will be invoked 144 * reflectively. 145 */ 146 private static Method findMethodForReflection(Method method) { 147 String altName = "reflected$" + method.getName(); 148 try { 149 return method.getDeclaringClass() 150 .getDeclaredMethod(altName, method.getParameterTypes()); 151 } catch (NoSuchMethodException ex) { 152 return null; 153 } 154 } 155 156 //-------------------------------------------------------------------------- 157 // 158 // Routines used by java.lang.reflect 159 // 160 // 161 162 /** Called only by java.lang.reflect.Modifier's static initializer */ 163 public void setLangReflectAccess(LangReflectAccess access) { 164 langReflectAccess = access; 165 } 166 167 /** 168 * Note: this routine can cause the declaring class for the field 169 * be initialized and therefore must not be called until the 170 * first get/set of this field. 171 * @param field the field 172 * @param override true if caller has overridden accessibility 173 */ 174 public FieldAccessor newFieldAccessor(Field field, boolean override) { 175 checkInitted(); 176 177 // use the root Field that will not cache caller class 178 Field f = langReflectAccess.getRoot(field); 179 if (f != null) { 180 field = f; 181 } 182 return UnsafeFieldAccessorFactory.newFieldAccessor(field, override); 183 } 184 185 public MethodAccessor newMethodAccessor(Method method) { 186 checkInitted(); 187 188 if (Reflection.isCallerSensitive(method)) { 189 Method altMethod = findMethodForReflection(method); 190 if (altMethod != null) { 191 method = altMethod; 192 } 193 } 194 195 // use the root Method that will not cache caller class 196 Method m = langReflectAccess.getRoot(method); 197 if (m != null) { 198 method = m; 199 } 200 201 if (noInflation && !ReflectUtil.isVMAnonymousClass(method.getDeclaringClass())) { 202 return new MethodAccessorGenerator(). 203 generateMethod(method.getDeclaringClass(), 204 method.getName(), 205 method.getParameterTypes(), 206 method.getReturnType(), 207 method.getExceptionTypes(), 208 method.getModifiers()); 209 } else { 210 NativeMethodAccessorImpl acc = 211 new NativeMethodAccessorImpl(method); 212 DelegatingMethodAccessorImpl res = 213 new DelegatingMethodAccessorImpl(acc); 214 acc.setParent(res); 215 return res; 216 } 217 } 218 219 public ConstructorAccessor newConstructorAccessor(Constructor<?> c) { 220 checkInitted(); 221 222 Class<?> declaringClass = c.getDeclaringClass(); 223 if (Modifier.isAbstract(declaringClass.getModifiers())) { 224 return new InstantiationExceptionConstructorAccessorImpl(null); 225 } 226 if (declaringClass == Class.class) { 227 return new InstantiationExceptionConstructorAccessorImpl 228 ("Can not instantiate java.lang.Class"); 229 } 230 231 // use the root Constructor that will not cache caller class 232 Constructor<?> ctr = langReflectAccess.getRoot(c); 233 if (ctr != null) { 234 c = ctr; 235 } 236 237 // Bootstrapping issue: since we use Class.newInstance() in 238 // the ConstructorAccessor generation process, we have to 239 // break the cycle here. 240 if (Reflection.isSubclassOf(declaringClass, 241 ConstructorAccessorImpl.class)) { 242 return new BootstrapConstructorAccessorImpl(c); 243 } 244 245 if (noInflation && !ReflectUtil.isVMAnonymousClass(c.getDeclaringClass())) { 246 return new MethodAccessorGenerator(). 247 generateConstructor(c.getDeclaringClass(), 248 c.getParameterTypes(), 249 c.getExceptionTypes(), 250 c.getModifiers()); 251 } else { 252 NativeConstructorAccessorImpl acc = 253 new NativeConstructorAccessorImpl(c); 254 DelegatingConstructorAccessorImpl res = 255 new DelegatingConstructorAccessorImpl(acc); 256 acc.setParent(res); 257 return res; 258 } 259 } 260 261 //-------------------------------------------------------------------------- 262 // 263 // Routines used by java.lang 264 // 265 // 266 267 /** Creates a new java.lang.reflect.Field. Access checks as per 268 java.lang.reflect.AccessibleObject are not overridden. */ 269 public Field newField(Class<?> declaringClass, 270 String name, 271 Class<?> type, 272 int modifiers, 273 int slot, 274 String signature, 275 byte[] annotations) 276 { 277 return langReflectAccess().newField(declaringClass, 278 name, 279 type, 280 modifiers, 281 slot, 282 signature, 283 annotations); 284 } 285 286 /** Creates a new java.lang.reflect.Method. Access checks as per 287 java.lang.reflect.AccessibleObject are not overridden. */ 288 public Method newMethod(Class<?> declaringClass, 289 String name, 290 Class<?>[] parameterTypes, 291 Class<?> returnType, 292 Class<?>[] checkedExceptions, 293 int modifiers, 294 int slot, 295 String signature, 296 byte[] annotations, 297 byte[] parameterAnnotations, 298 byte[] annotationDefault) 299 { 300 return langReflectAccess().newMethod(declaringClass, 301 name, 302 parameterTypes, 303 returnType, 304 checkedExceptions, 305 modifiers, 306 slot, 307 signature, 308 annotations, 309 parameterAnnotations, 310 annotationDefault); 311 } 312 313 /** Creates a new java.lang.reflect.Constructor. Access checks as 314 per java.lang.reflect.AccessibleObject are not overridden. */ 315 public Constructor<?> newConstructor(Class<?> declaringClass, 316 Class<?>[] parameterTypes, 317 Class<?>[] checkedExceptions, 318 int modifiers, 319 int slot, 320 String signature, 321 byte[] annotations, 322 byte[] parameterAnnotations) 323 { 324 return langReflectAccess().newConstructor(declaringClass, 325 parameterTypes, 326 checkedExceptions, 327 modifiers, 328 slot, 329 signature, 330 annotations, 331 parameterAnnotations); 332 } 333 334 /** Gets the MethodAccessor object for a java.lang.reflect.Method */ 335 public MethodAccessor getMethodAccessor(Method m) { 336 return langReflectAccess().getMethodAccessor(m); 337 } 338 339 /** Sets the MethodAccessor object for a java.lang.reflect.Method */ 340 public void setMethodAccessor(Method m, MethodAccessor accessor) { 341 langReflectAccess().setMethodAccessor(m, accessor); 342 } 343 344 /** Gets the ConstructorAccessor object for a 345 java.lang.reflect.Constructor */ 346 public ConstructorAccessor getConstructorAccessor(Constructor<?> c) { 347 return langReflectAccess().getConstructorAccessor(c); 348 } 349 350 /** Sets the ConstructorAccessor object for a 351 java.lang.reflect.Constructor */ 352 public void setConstructorAccessor(Constructor<?> c, 353 ConstructorAccessor accessor) 354 { 355 langReflectAccess().setConstructorAccessor(c, accessor); 356 } 357 358 /** Makes a copy of the passed method. The returned method is a 359 "child" of the passed one; see the comments in Method.java for 360 details. */ 361 public Method copyMethod(Method arg) { 362 return langReflectAccess().copyMethod(arg); 363 } 364 365 /** Makes a copy of the passed method. The returned method is NOT 366 * a "child" but a "sibling" of the Method in arg. Should only be 367 * used on non-root methods. */ 368 public Method leafCopyMethod(Method arg) { 369 return langReflectAccess().leafCopyMethod(arg); 370 } 371 372 373 /** Makes a copy of the passed field. The returned field is a 374 "child" of the passed one; see the comments in Field.java for 375 details. */ 376 public Field copyField(Field arg) { 377 return langReflectAccess().copyField(arg); 378 } 379 380 /** Makes a copy of the passed constructor. The returned 381 constructor is a "child" of the passed one; see the comments 382 in Constructor.java for details. */ 383 public <T> Constructor<T> copyConstructor(Constructor<T> arg) { 384 return langReflectAccess().copyConstructor(arg); 385 } 386 387 /** Gets the byte[] that encodes TypeAnnotations on an executable. 388 */ 389 public byte[] getExecutableTypeAnnotationBytes(Executable ex) { 390 return langReflectAccess().getExecutableTypeAnnotationBytes(ex); 391 } 392 393 public Class<?>[] getExecutableSharedParameterTypes(Executable ex) { 394 return langReflectAccess().getExecutableSharedParameterTypes(ex); 395 } 396 397 //-------------------------------------------------------------------------- 398 // 399 // Routines used by serialization 400 // 401 // 402 403 public final Constructor<?> newConstructorForExternalization(Class<?> cl) { 404 if (!Externalizable.class.isAssignableFrom(cl)) { 405 return null; 406 } 407 try { 408 Constructor<?> cons = cl.getConstructor(); 409 cons.setAccessible(true); 410 return cons; 411 } catch (NoSuchMethodException ex) { 412 return null; 413 } 414 } 415 416 public final Constructor<?> newConstructorForSerialization(Class<?> cl, 417 Constructor<?> constructorToCall) 418 { 419 if (constructorToCall.getDeclaringClass() == cl) { 420 constructorToCall.setAccessible(true); 421 return constructorToCall; 422 } 423 return generateConstructor(cl, constructorToCall); 424 } 425 426 public final Constructor<?> newConstructorForSerialization(Class<?> cl) { 427 Class<?> initCl = cl; 428 while (Serializable.class.isAssignableFrom(initCl)) { 429 if ((initCl = initCl.getSuperclass()) == null) { 430 return null; 431 } 432 } 433 Constructor<?> constructorToCall; 434 try { 435 constructorToCall = initCl.getDeclaredConstructor(); 436 int mods = constructorToCall.getModifiers(); 437 if ((mods & Modifier.PRIVATE) != 0 || 438 ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 && 439 !packageEquals(cl, initCl))) { 440 return null; 441 } 442 } catch (NoSuchMethodException ex) { 443 return null; 444 } 445 return generateConstructor(cl, constructorToCall); 446 } 447 448 private final Constructor<?> generateConstructor(Class<?> cl, 449 Constructor<?> constructorToCall) { 450 451 452 ConstructorAccessor acc = new MethodAccessorGenerator(). 453 generateSerializationConstructor(cl, 454 constructorToCall.getParameterTypes(), 455 constructorToCall.getExceptionTypes(), 456 constructorToCall.getModifiers(), 457 constructorToCall.getDeclaringClass()); 458 Constructor<?> c = newConstructor(constructorToCall.getDeclaringClass(), 459 constructorToCall.getParameterTypes(), 460 constructorToCall.getExceptionTypes(), 461 constructorToCall.getModifiers(), 462 langReflectAccess(). 463 getConstructorSlot(constructorToCall), 464 langReflectAccess(). 465 getConstructorSignature(constructorToCall), 466 langReflectAccess(). 467 getConstructorAnnotations(constructorToCall), 468 langReflectAccess(). 469 getConstructorParameterAnnotations(constructorToCall)); 470 setConstructorAccessor(c, acc); 471 c.setAccessible(true); 472 return c; 473 } 474 475 public final MethodHandle readObjectForSerialization(Class<?> cl) { 476 return findReadWriteObjectForSerialization(cl, "readObject", ObjectInputStream.class); 477 } 478 479 public final MethodHandle readObjectNoDataForSerialization(Class<?> cl) { 480 return findReadWriteObjectForSerialization(cl, "readObjectNoData", ObjectInputStream.class); 481 } 482 483 public final MethodHandle writeObjectForSerialization(Class<?> cl) { 484 return findReadWriteObjectForSerialization(cl, "writeObject", ObjectOutputStream.class); 485 } 486 487 private final MethodHandle findReadWriteObjectForSerialization(Class<?> cl, 488 String methodName, 489 Class<?> streamClass) { 490 if (!Serializable.class.isAssignableFrom(cl)) { 491 return null; 492 } 493 494 try { 495 Method meth = cl.getDeclaredMethod(methodName, streamClass); 496 int mods = meth.getModifiers(); 497 if (meth.getReturnType() != Void.TYPE || 498 Modifier.isStatic(mods) || 499 !Modifier.isPrivate(mods)) { 500 return null; 501 } 502 meth.setAccessible(true); 503 return MethodHandles.lookup().unreflect(meth); 504 } catch (NoSuchMethodException ex) { 505 return null; 506 } catch (IllegalAccessException ex1) { 507 throw new InternalError("Error", ex1); 508 } 509 } 510 511 /** 512 * Returns a MethodHandle for {@code writeReplace} on the serializable class 513 * or null if no match found. 514 * @param cl a serializable class 515 * @returnss the {@code writeReplace} MethodHandle or {@code null} if not found 516 */ 517 public final MethodHandle writeReplaceForSerialization(Class<?> cl) { 518 return getReplaceResolveForSerialization(cl, "writeReplace"); 519 } 520 521 /** 522 * Returns a MethodHandle for {@code readResolve} on the serializable class 523 * or null if no match found. 524 * @param cl a serializable class 525 * @returns the {@code writeReplace} MethodHandle or {@code null} if not found 526 */ 527 public final MethodHandle readResolveForSerialization(Class<?> cl) { 528 return getReplaceResolveForSerialization(cl, "readResolve"); 529 } 530 531 /** 532 * Lookup readResolve or writeReplace on a class with specified 533 * signature constraints. 534 * @param cl a serializable class 535 * @param methodName the method name to find 536 * @returns a MethodHandle for the method or {@code null} if not found or 537 * has the wrong signature. 538 */ 539 private MethodHandle getReplaceResolveForSerialization(Class<?> cl, 540 String methodName) { 541 if (!Serializable.class.isAssignableFrom(cl)) { 542 return null; 543 } 544 545 Class<?> defCl = cl; 546 while (defCl != null) { 547 try { 548 Method m = defCl.getDeclaredMethod(methodName); 549 if (m.getReturnType() != Object.class) { 550 return null; 551 } 552 int mods = m.getModifiers(); 553 if (Modifier.isStatic(mods) | Modifier.isAbstract(mods)) { 554 return null; 555 } else if (Modifier.isPublic(mods) | Modifier.isProtected(mods)) { 556 // fall through 557 } else if (Modifier.isPrivate(mods) && (cl != defCl)) { 558 return null; 559 } else if (!packageEquals(cl, defCl)) { 560 return null; 561 } 562 try { 563 // Normal return 564 m.setAccessible(true); 565 return MethodHandles.lookup().unreflect(m); 566 } catch (IllegalAccessException ex0) { 567 // setAccessible should prevent IAE 568 throw new InternalError("Error", ex0); 569 } 570 } catch (NoSuchMethodException ex) { 571 defCl = defCl.getSuperclass(); 572 } 573 } 574 return null; 575 } 576 577 /** 578 * Returns true if the given class defines a static initializer method, 579 * false otherwise. 580 */ 581 public final boolean hasStaticInitializerForSerialization(Class<?> cl) { 582 Method m = hasStaticInitializerMethod; 583 if (m == null) { 584 try { 585 m = ObjectStreamClass.class.getDeclaredMethod("hasStaticInitializer", 586 new Class<?>[]{Class.class}); 587 m.setAccessible(true); 588 hasStaticInitializerMethod = m; 589 } catch (NoSuchMethodException ex) { 590 throw new InternalError("No such method hasStaticInitializer on " 591 + ObjectStreamClass.class, ex); 592 } 593 } 594 try { 595 return (Boolean) m.invoke(null, cl); 596 } catch (InvocationTargetException | IllegalAccessException ex) { 597 throw new InternalError("Exception invoking hasStaticInitializer", ex); 598 } 599 } 600 601 /** 602 * Return the accessible constructor for OptionalDataException signaling eof. 603 * @returns the eof constructor for OptionalDataException 604 */ 605 public final Constructor<OptionalDataException> newOptionalDataExceptionForSerialization() { 606 try { 607 Constructor<OptionalDataException> boolCtor = 608 OptionalDataException.class.getDeclaredConstructor(Boolean.TYPE); 609 boolCtor.setAccessible(true); 610 return boolCtor; 611 } catch (NoSuchMethodException ex) { 612 throw new InternalError("Constructor not found", ex); 613 } 614 } 615 616 //-------------------------------------------------------------------------- 617 // 618 // Internals only below this point 619 // 620 621 static int inflationThreshold() { 622 return inflationThreshold; 623 } 624 625 /** We have to defer full initialization of this class until after 626 the static initializer is run since java.lang.reflect.Method's 627 static initializer (more properly, that for 628 java.lang.reflect.AccessibleObject) causes this class's to be 629 run, before the system properties are set up. */ 630 private static void checkInitted() { 631 if (initted) return; 632 633 // Defer initialization until module system is initialized so as 634 // to avoid inflation and spinning bytecode in unnamed modules 635 // during early startup. 636 if (!VM.isModuleSystemInited()) { 637 return; 638 } 639 640 Properties props = GetPropertyAction.privilegedGetProperties(); 641 String val = props.getProperty("sun.reflect.noInflation"); 642 if (val != null && val.equals("true")) { 643 noInflation = true; 644 } 645 646 val = props.getProperty("sun.reflect.inflationThreshold"); 647 if (val != null) { 648 try { 649 inflationThreshold = Integer.parseInt(val); 650 } catch (NumberFormatException e) { 651 throw new RuntimeException("Unable to parse property sun.reflect.inflationThreshold", e); 652 } 653 } 654 655 initted = true; 656 } 657 658 private static LangReflectAccess langReflectAccess() { 659 if (langReflectAccess == null) { 660 // Call a static method to get class java.lang.reflect.Modifier 661 // initialized. Its static initializer will cause 662 // setLangReflectAccess() to be called from the context of the 663 // java.lang.reflect package. 664 Modifier.isPublic(Modifier.PUBLIC); 665 } 666 return langReflectAccess; 667 } 668 669 /** 670 * Returns true if classes are defined in the classloader and same package, false 671 * otherwise. 672 * @param cl1 a class 673 * @param cl2 another class 674 * @returns true if the two classes are in the same classloader and package 675 */ 676 private static boolean packageEquals(Class<?> cl1, Class<?> cl2) { 677 return cl1.getClassLoader() == cl2.getClassLoader() && 678 Objects.equals(cl1.getPackage(), cl2.getPackage()); 679 } 680 681 }