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