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 return UnsafeFieldAccessorFactory.newFieldAccessor(field, override); 177 } 178 179 public MethodAccessor newMethodAccessor(Method method) { 180 checkInitted(); 181 182 boolean noInflation = ReflectionFactory.noInflation; 183 if (Reflection.isCallerSensitive(method)) { 184 Method altMethod = findMethodForReflection(method); 185 if (altMethod != null) { 186 method = altMethod; 187 noInflation = true; // in this case only 188 } 189 } 190 191 if (noInflation && !ReflectUtil.isVMAnonymousClass(method.getDeclaringClass())) { 192 return new MethodAccessorGenerator(). 193 generateMethod(method.getDeclaringClass(), 194 method.getName(), 195 method.getParameterTypes(), 196 method.getReturnType(), 197 method.getExceptionTypes(), 198 method.getModifiers()); 199 } else { 200 NativeMethodAccessorImpl acc = 201 new NativeMethodAccessorImpl(method); 202 DelegatingMethodAccessorImpl res = 203 new DelegatingMethodAccessorImpl(acc); 204 acc.setParent(res); 205 return res; 206 } 207 } 208 209 public ConstructorAccessor newConstructorAccessor(Constructor<?> c) { 210 checkInitted(); 211 212 Class<?> declaringClass = c.getDeclaringClass(); 213 if (Modifier.isAbstract(declaringClass.getModifiers())) { 214 return new InstantiationExceptionConstructorAccessorImpl(null); 215 } 216 if (declaringClass == Class.class) { 217 return new InstantiationExceptionConstructorAccessorImpl 218 ("Can not instantiate java.lang.Class"); 219 } 220 // Bootstrapping issue: since we use Class.newInstance() in 221 // the ConstructorAccessor generation process, we have to 222 // break the cycle here. 223 if (Reflection.isSubclassOf(declaringClass, 224 ConstructorAccessorImpl.class)) { 225 return new BootstrapConstructorAccessorImpl(c); 226 } 227 228 if (noInflation && !ReflectUtil.isVMAnonymousClass(c.getDeclaringClass())) { 229 return new MethodAccessorGenerator(). 230 generateConstructor(c.getDeclaringClass(), 231 c.getParameterTypes(), 232 c.getExceptionTypes(), 233 c.getModifiers()); 234 } else { 235 NativeConstructorAccessorImpl acc = 236 new NativeConstructorAccessorImpl(c); 237 DelegatingConstructorAccessorImpl res = 238 new DelegatingConstructorAccessorImpl(acc); 239 acc.setParent(res); 240 return res; 241 } 242 } 243 244 //-------------------------------------------------------------------------- 245 // 246 // Routines used by java.lang 247 // 248 // 249 250 /** Creates a new java.lang.reflect.Field. Access checks as per 251 java.lang.reflect.AccessibleObject are not overridden. */ 252 public Field newField(Class<?> declaringClass, 253 String name, 254 Class<?> type, 255 int modifiers, 256 int slot, 257 String signature, 258 byte[] annotations) 259 { 260 return langReflectAccess().newField(declaringClass, 261 name, 262 type, 263 modifiers, 264 slot, 265 signature, 266 annotations); 267 } 268 269 /** Creates a new java.lang.reflect.Method. Access checks as per 270 java.lang.reflect.AccessibleObject are not overridden. */ 271 public Method newMethod(Class<?> declaringClass, 272 String name, 273 Class<?>[] parameterTypes, 274 Class<?> returnType, 275 Class<?>[] checkedExceptions, 276 int modifiers, 277 int slot, 278 String signature, 279 byte[] annotations, 280 byte[] parameterAnnotations, 281 byte[] annotationDefault) 282 { 283 return langReflectAccess().newMethod(declaringClass, 284 name, 285 parameterTypes, 286 returnType, 287 checkedExceptions, 288 modifiers, 289 slot, 290 signature, 291 annotations, 292 parameterAnnotations, 293 annotationDefault); 294 } 295 296 /** Creates a new java.lang.reflect.Constructor. Access checks as 297 per java.lang.reflect.AccessibleObject are not overridden. */ 298 public Constructor<?> newConstructor(Class<?> declaringClass, 299 Class<?>[] parameterTypes, 300 Class<?>[] checkedExceptions, 301 int modifiers, 302 int slot, 303 String signature, 304 byte[] annotations, 305 byte[] parameterAnnotations) 306 { 307 return langReflectAccess().newConstructor(declaringClass, 308 parameterTypes, 309 checkedExceptions, 310 modifiers, 311 slot, 312 signature, 313 annotations, 314 parameterAnnotations); 315 } 316 317 /** Gets the MethodAccessor object for a java.lang.reflect.Method */ 318 public MethodAccessor getMethodAccessor(Method m) { 319 return langReflectAccess().getMethodAccessor(m); 320 } 321 322 /** Sets the MethodAccessor object for a java.lang.reflect.Method */ 323 public void setMethodAccessor(Method m, MethodAccessor accessor) { 324 langReflectAccess().setMethodAccessor(m, accessor); 325 } 326 327 /** Gets the ConstructorAccessor object for a 328 java.lang.reflect.Constructor */ 329 public ConstructorAccessor getConstructorAccessor(Constructor<?> c) { 330 return langReflectAccess().getConstructorAccessor(c); 331 } 332 333 /** Sets the ConstructorAccessor object for a 334 java.lang.reflect.Constructor */ 335 public void setConstructorAccessor(Constructor<?> c, 336 ConstructorAccessor accessor) 337 { 338 langReflectAccess().setConstructorAccessor(c, accessor); 339 } 340 341 /** Makes a copy of the passed method. The returned method is a 342 "child" of the passed one; see the comments in Method.java for 343 details. */ 344 public Method copyMethod(Method arg) { 345 return langReflectAccess().copyMethod(arg); 346 } 347 348 /** Makes a copy of the passed method. The returned method is NOT 349 * a "child" but a "sibling" of the Method in arg. Should only be 350 * used on non-root methods. */ 351 public Method leafCopyMethod(Method arg) { 352 return langReflectAccess().leafCopyMethod(arg); 353 } 354 355 356 /** Makes a copy of the passed field. The returned field is a 357 "child" of the passed one; see the comments in Field.java for 358 details. */ 359 public Field copyField(Field arg) { 360 return langReflectAccess().copyField(arg); 361 } 362 363 /** Makes a copy of the passed constructor. The returned 364 constructor is a "child" of the passed one; see the comments 365 in Constructor.java for details. */ 366 public <T> Constructor<T> copyConstructor(Constructor<T> arg) { 367 return langReflectAccess().copyConstructor(arg); 368 } 369 370 /** Gets the byte[] that encodes TypeAnnotations on an executable. 371 */ 372 public byte[] getExecutableTypeAnnotationBytes(Executable ex) { 373 return langReflectAccess().getExecutableTypeAnnotationBytes(ex); 374 } 375 376 public Class<?>[] getExecutableSharedParameterTypes(Executable ex) { 377 return langReflectAccess().getExecutableSharedParameterTypes(ex); 378 } 379 380 //-------------------------------------------------------------------------- 381 // 382 // Routines used by serialization 383 // 384 // 385 386 public final Constructor<?> newConstructorForExternalization(Class<?> cl) { 387 if (!Externalizable.class.isAssignableFrom(cl)) { 388 return null; 389 } 390 try { 391 Constructor<?> cons = cl.getConstructor(); 392 cons.setAccessible(true); 393 return cons; 394 } catch (NoSuchMethodException ex) { 395 return null; 396 } 397 } 398 399 public final Constructor<?> newConstructorForSerialization(Class<?> cl, 400 Constructor<?> constructorToCall) 401 { 402 if (constructorToCall.getDeclaringClass() == cl) { 403 constructorToCall.setAccessible(true); 404 return constructorToCall; 405 } 406 return generateConstructor(cl, constructorToCall); 407 } 408 409 public final Constructor<?> newConstructorForSerialization(Class<?> cl) { 410 Class<?> initCl = cl; 411 while (Serializable.class.isAssignableFrom(initCl)) { 412 if ((initCl = initCl.getSuperclass()) == null) { 413 return null; 414 } 415 } 416 Constructor<?> constructorToCall; 417 try { 418 constructorToCall = initCl.getDeclaredConstructor(); 419 int mods = constructorToCall.getModifiers(); 420 if ((mods & Modifier.PRIVATE) != 0 || 421 ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 && 422 !packageEquals(cl, initCl))) { 423 return null; 424 } 425 } catch (NoSuchMethodException ex) { 426 return null; 427 } 428 return generateConstructor(cl, constructorToCall); 429 } 430 431 private final Constructor<?> generateConstructor(Class<?> cl, 432 Constructor<?> constructorToCall) { 433 434 435 ConstructorAccessor acc = new MethodAccessorGenerator(). 436 generateSerializationConstructor(cl, 437 constructorToCall.getParameterTypes(), 438 constructorToCall.getExceptionTypes(), 439 constructorToCall.getModifiers(), 440 constructorToCall.getDeclaringClass()); 441 Constructor<?> c = newConstructor(constructorToCall.getDeclaringClass(), 442 constructorToCall.getParameterTypes(), 443 constructorToCall.getExceptionTypes(), 444 constructorToCall.getModifiers(), 445 langReflectAccess(). 446 getConstructorSlot(constructorToCall), 447 langReflectAccess(). 448 getConstructorSignature(constructorToCall), 449 langReflectAccess(). 450 getConstructorAnnotations(constructorToCall), 451 langReflectAccess(). 452 getConstructorParameterAnnotations(constructorToCall)); 453 setConstructorAccessor(c, acc); 454 c.setAccessible(true); 455 return c; 456 } 457 458 public final MethodHandle readObjectForSerialization(Class<?> cl) { 459 return findReadWriteObjectForSerialization(cl, "readObject", ObjectInputStream.class); 460 } 461 462 public final MethodHandle readObjectNoDataForSerialization(Class<?> cl) { 463 return findReadWriteObjectForSerialization(cl, "readObjectNoData", ObjectInputStream.class); 464 } 465 466 public final MethodHandle writeObjectForSerialization(Class<?> cl) { 467 return findReadWriteObjectForSerialization(cl, "writeObject", ObjectOutputStream.class); 468 } 469 470 private final MethodHandle findReadWriteObjectForSerialization(Class<?> cl, 471 String methodName, 472 Class<?> streamClass) { 473 if (!Serializable.class.isAssignableFrom(cl)) { 474 return null; 475 } 476 477 try { 478 Method meth = cl.getDeclaredMethod(methodName, streamClass); 479 int mods = meth.getModifiers(); 480 if (meth.getReturnType() != Void.TYPE || 481 Modifier.isStatic(mods) || 482 !Modifier.isPrivate(mods)) { 483 return null; 484 } 485 meth.setAccessible(true); 486 return MethodHandles.lookup().unreflect(meth); 487 } catch (NoSuchMethodException ex) { 488 return null; 489 } catch (IllegalAccessException ex1) { 490 throw new InternalError("Error", ex1); 491 } 492 } 493 494 /** 495 * Returns a MethodHandle for {@code writeReplace} on the serializable class 496 * or null if no match found. 497 * @param cl a serializable class 498 * @returnss the {@code writeReplace} MethodHandle or {@code null} if not found 499 */ 500 public final MethodHandle writeReplaceForSerialization(Class<?> cl) { 501 return getReplaceResolveForSerialization(cl, "writeReplace"); 502 } 503 504 /** 505 * Returns a MethodHandle for {@code readResolve} on the serializable class 506 * or null if no match found. 507 * @param cl a serializable class 508 * @returns the {@code writeReplace} MethodHandle or {@code null} if not found 509 */ 510 public final MethodHandle readResolveForSerialization(Class<?> cl) { 511 return getReplaceResolveForSerialization(cl, "readResolve"); 512 } 513 514 /** 515 * Lookup readResolve or writeReplace on a class with specified 516 * signature constraints. 517 * @param cl a serializable class 518 * @param methodName the method name to find 519 * @returns a MethodHandle for the method or {@code null} if not found or 520 * has the wrong signature. 521 */ 522 private MethodHandle getReplaceResolveForSerialization(Class<?> cl, 523 String methodName) { 524 if (!Serializable.class.isAssignableFrom(cl)) { 525 return null; 526 } 527 528 Class<?> defCl = cl; 529 while (defCl != null) { 530 try { 531 Method m = defCl.getDeclaredMethod(methodName); 532 if (m.getReturnType() != Object.class) { 533 return null; 534 } 535 int mods = m.getModifiers(); 536 if (Modifier.isStatic(mods) | Modifier.isAbstract(mods)) { 537 return null; 538 } else if (Modifier.isPublic(mods) | Modifier.isProtected(mods)) { 539 // fall through 540 } else if (Modifier.isPrivate(mods) && (cl != defCl)) { 541 return null; 542 } else if (!packageEquals(cl, defCl)) { 543 return null; 544 } 545 try { 546 // Normal return 547 m.setAccessible(true); 548 return MethodHandles.lookup().unreflect(m); 549 } catch (IllegalAccessException ex0) { 550 // setAccessible should prevent IAE 551 throw new InternalError("Error", ex0); 552 } 553 } catch (NoSuchMethodException ex) { 554 defCl = defCl.getSuperclass(); 555 } 556 } 557 return null; 558 } 559 560 /** 561 * Returns true if the given class defines a static initializer method, 562 * false otherwise. 563 */ 564 public final boolean hasStaticInitializerForSerialization(Class<?> cl) { 565 Method m = hasStaticInitializerMethod; 566 if (m == null) { 567 try { 568 m = ObjectStreamClass.class.getDeclaredMethod("hasStaticInitializer", 569 new Class<?>[]{Class.class}); 570 m.setAccessible(true); 571 hasStaticInitializerMethod = m; 572 } catch (NoSuchMethodException ex) { 573 throw new InternalError("No such method hasStaticInitializer on " 574 + ObjectStreamClass.class, ex); 575 } 576 } 577 try { 578 return (Boolean) m.invoke(null, cl); 579 } catch (InvocationTargetException | IllegalAccessException ex) { 580 throw new InternalError("Exception invoking hasStaticInitializer", ex); 581 } 582 } 583 584 /** 585 * Return the accessible constructor for OptionalDataException signaling eof. 586 * @returns the eof constructor for OptionalDataException 587 */ 588 public final Constructor<OptionalDataException> newOptionalDataExceptionForSerialization() { 589 try { 590 Constructor<OptionalDataException> boolCtor = 591 OptionalDataException.class.getDeclaredConstructor(Boolean.TYPE); 592 boolCtor.setAccessible(true); 593 return boolCtor; 594 } catch (NoSuchMethodException ex) { 595 throw new InternalError("Constructor not found", ex); 596 } 597 } 598 599 //-------------------------------------------------------------------------- 600 // 601 // Internals only below this point 602 // 603 604 static int inflationThreshold() { 605 return inflationThreshold; 606 } 607 608 /** We have to defer full initialization of this class until after 609 the static initializer is run since java.lang.reflect.Method's 610 static initializer (more properly, that for 611 java.lang.reflect.AccessibleObject) causes this class's to be 612 run, before the system properties are set up. */ 613 private static void checkInitted() { 614 if (initted) return; 615 616 // Defer initialization until module system is initialized so as 617 // to avoid inflation and spinning bytecode in unnamed modules 618 // during early startup. 619 if (!VM.isModuleSystemInited()) { 620 return; 621 } 622 623 Properties props = GetPropertyAction.privilegedGetProperties(); 624 String val = props.getProperty("sun.reflect.noInflation"); 625 if (val != null && val.equals("true")) { 626 noInflation = true; 627 } 628 629 val = props.getProperty("sun.reflect.inflationThreshold"); 630 if (val != null) { 631 try { 632 inflationThreshold = Integer.parseInt(val); 633 } catch (NumberFormatException e) { 634 throw new RuntimeException("Unable to parse property sun.reflect.inflationThreshold", e); 635 } 636 } 637 638 initted = true; 639 } 640 641 private static LangReflectAccess langReflectAccess() { 642 if (langReflectAccess == null) { 643 // Call a static method to get class java.lang.reflect.Modifier 644 // initialized. Its static initializer will cause 645 // setLangReflectAccess() to be called from the context of the 646 // java.lang.reflect package. 647 Modifier.isPublic(Modifier.PUBLIC); 648 } 649 return langReflectAccess; 650 } 651 652 /** 653 * Returns true if classes are defined in the classloader and same package, false 654 * otherwise. 655 * @param cl1 a class 656 * @param cl2 another class 657 * @returns true if the two classes are in the same classloader and package 658 */ 659 private static boolean packageEquals(Class<?> cl1, Class<?> cl2) { 660 return cl1.getClassLoader() == cl2.getClassLoader() && 661 Objects.equals(cl1.getPackage(), cl2.getPackage()); 662 } 663 664 }