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