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