1 /* 2 * Copyright (c) 2001, 2023, 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.Constructor; 37 import java.lang.reflect.Executable; 38 import java.lang.reflect.Field; 39 import java.lang.reflect.InvocationTargetException; 40 import java.lang.reflect.Method; 41 import java.lang.reflect.Modifier; 42 import java.security.PrivilegedAction; 43 import java.util.Properties; 44 import jdk.internal.access.JavaLangReflectAccess; 45 import jdk.internal.access.SharedSecrets; 46 import jdk.internal.misc.VM; 47 import jdk.internal.vm.annotation.Stable; 48 import sun.security.action.GetPropertyAction; 49 import sun.security.util.SecurityConstants; 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 final ReflectionFactory soleInstance = new ReflectionFactory(); 66 67 68 /* Method for static class initializer <clinit>, or null */ 69 private static volatile Method hasStaticInitializerMethod; 70 71 private final JavaLangReflectAccess langReflectAccess; 72 private ReflectionFactory() { 73 this.langReflectAccess = SharedSecrets.getJavaLangReflectAccess(); 74 } 75 76 /** 77 * A convenience class for acquiring the capability to instantiate 78 * reflective objects. Use this instead of a raw call to {@link 79 * #getReflectionFactory} in order to avoid being limited by the 80 * permissions of your callers. 81 * 82 * <p>An instance of this class can be used as the argument of 83 * <code>AccessController.doPrivileged</code>. 84 */ 85 public static final class GetReflectionFactoryAction 86 implements PrivilegedAction<ReflectionFactory> { 87 public ReflectionFactory run() { 88 return getReflectionFactory(); 89 } 90 } 91 92 /** 93 * Provides the caller with the capability to instantiate reflective 94 * objects. 95 * 96 * <p> First, if there is a security manager, its 97 * <code>checkPermission</code> method is called with a {@link 98 * java.lang.RuntimePermission} with target 99 * <code>"reflectionFactoryAccess"</code>. This may result in a 100 * security exception. 101 * 102 * <p> The returned <code>ReflectionFactory</code> object should be 103 * carefully guarded by the caller, since it can be used to read and 104 * write private data and invoke private methods, as well as to load 105 * unverified bytecodes. It must never be passed to untrusted code. 106 * 107 * @exception SecurityException if a security manager exists and its 108 * <code>checkPermission</code> method doesn't allow 109 * access to the RuntimePermission "reflectionFactoryAccess". */ 110 public static ReflectionFactory getReflectionFactory() { 111 @SuppressWarnings("removal") 112 SecurityManager security = System.getSecurityManager(); 113 if (security != null) { 114 security.checkPermission( 115 SecurityConstants.REFLECTION_FACTORY_ACCESS_PERMISSION); 116 } 117 return soleInstance; 118 } 119 120 //-------------------------------------------------------------------------- 121 // 122 // Routines used by java.lang.reflect 123 // 124 // 125 126 /* 127 * Note: this routine can cause the declaring class for the field 128 * be initialized and therefore must not be called until the 129 * first get/set of this field. 130 * @param field the field 131 * @param override true if caller has overridden accessibility 132 */ 133 public FieldAccessor newFieldAccessor(Field field, boolean override) { 134 Field root = langReflectAccess.getRoot(field); 135 if (root != null) { 136 // FieldAccessor will use the root unless the modifiers have 137 // been overridden 138 if (root.getModifiers() == field.getModifiers() || !override) { 139 field = root; 140 } 141 } 142 boolean isFinal = Modifier.isFinal(field.getModifiers()); 143 boolean isReadOnly = isFinal && (!override || langReflectAccess.isTrustedFinalField(field)); 144 return MethodHandleAccessorFactory.newFieldAccessor(field, isReadOnly); 145 } 146 147 public MethodAccessor newMethodAccessor(Method method, boolean callerSensitive) { 148 // use the root Method that will not cache caller class 149 Method root = langReflectAccess.getRoot(method); 150 if (root != null) { 151 method = root; 152 } 153 154 return MethodHandleAccessorFactory.newMethodAccessor(method, callerSensitive); 155 } 156 157 public ConstructorAccessor newConstructorAccessor(Constructor<?> c) { 158 Class<?> declaringClass = c.getDeclaringClass(); 159 if (Modifier.isAbstract(declaringClass.getModifiers())) { 160 return new InstantiationExceptionConstructorAccessorImpl(null); 161 } 162 if (declaringClass == Class.class) { 163 return new InstantiationExceptionConstructorAccessorImpl 164 ("Can not instantiate java.lang.Class"); 165 } 166 167 // use the root Constructor that will not cache caller class 168 Constructor<?> root = langReflectAccess.getRoot(c); 169 if (root != null) { 170 c = root; 171 } 172 173 return MethodHandleAccessorFactory.newConstructorAccessor(c); 174 } 175 176 //-------------------------------------------------------------------------- 177 // 178 // Routines used by java.lang 179 // 180 // 181 182 /** Creates a new java.lang.reflect.Constructor. Access checks as 183 per java.lang.reflect.AccessibleObject are not overridden. */ 184 public Constructor<?> newConstructor(Class<?> declaringClass, 185 Class<?>[] parameterTypes, 186 Class<?>[] checkedExceptions, 187 int modifiers, 188 int slot, 189 String signature, 190 byte[] annotations, 191 byte[] parameterAnnotations) 192 { 193 return langReflectAccess.newConstructor(declaringClass, 194 parameterTypes, 195 checkedExceptions, 196 modifiers, 197 slot, 198 signature, 199 annotations, 200 parameterAnnotations); 201 } 202 203 /** Gets the ConstructorAccessor object for a 204 java.lang.reflect.Constructor */ 205 public ConstructorAccessor getConstructorAccessor(Constructor<?> c) { 206 return langReflectAccess.getConstructorAccessor(c); 207 } 208 209 /** Sets the ConstructorAccessor object for a 210 java.lang.reflect.Constructor */ 211 public void setConstructorAccessor(Constructor<?> c, 212 ConstructorAccessor accessor) 213 { 214 langReflectAccess.setConstructorAccessor(c, accessor); 215 } 216 217 /** Makes a copy of the passed method. The returned method is a 218 "child" of the passed one; see the comments in Method.java for 219 details. */ 220 public Method copyMethod(Method arg) { 221 return langReflectAccess.copyMethod(arg); 222 } 223 224 /** Makes a copy of the passed method. The returned method is NOT 225 * a "child" but a "sibling" of the Method in arg. Should only be 226 * used on non-root methods. */ 227 public Method leafCopyMethod(Method arg) { 228 return langReflectAccess.leafCopyMethod(arg); 229 } 230 231 232 /** Makes a copy of the passed field. The returned field is a 233 "child" of the passed one; see the comments in Field.java for 234 details. */ 235 public Field copyField(Field arg) { 236 return langReflectAccess.copyField(arg); 237 } 238 239 /** Makes a copy of the passed constructor. The returned 240 constructor is a "child" of the passed one; see the comments 241 in Constructor.java for details. */ 242 public <T> Constructor<T> copyConstructor(Constructor<T> arg) { 243 return langReflectAccess.copyConstructor(arg); 244 } 245 246 /** Gets the byte[] that encodes TypeAnnotations on an executable. 247 */ 248 public byte[] getExecutableTypeAnnotationBytes(Executable ex) { 249 return langReflectAccess.getExecutableTypeAnnotationBytes(ex); 250 } 251 252 public Class<?>[] getExecutableSharedParameterTypes(Executable ex) { 253 return langReflectAccess.getExecutableSharedParameterTypes(ex); 254 } 255 256 public <T> T newInstance(Constructor<T> ctor, Object[] args, Class<?> caller) 257 throws IllegalAccessException, InstantiationException, InvocationTargetException 258 { 259 return langReflectAccess.newInstance(ctor, args, caller); 260 } 261 262 //-------------------------------------------------------------------------- 263 // 264 // Routines used by serialization 265 // 266 // 267 268 public final Constructor<?> newConstructorForExternalization(Class<?> cl) { 269 if (!Externalizable.class.isAssignableFrom(cl)) { 270 return null; 271 } 272 if (cl.isValue()) { 273 throw new UnsupportedOperationException("newConstructorForExternalization does not support value classes"); 274 } 275 try { 276 Constructor<?> cons = cl.getConstructor(); 277 cons.setAccessible(true); 278 return cons; 279 } catch (NoSuchMethodException ex) { 280 return null; 281 } 282 } 283 284 public final Constructor<?> newConstructorForSerialization(Class<?> cl, 285 Constructor<?> constructorToCall) 286 { 287 if (constructorToCall.getDeclaringClass() == cl) { 288 constructorToCall.setAccessible(true); 289 return constructorToCall; 290 } 291 if (cl.isValue()) { 292 throw new UnsupportedOperationException("newConstructorForSerialization does not support value classes"); 293 } 294 return generateConstructor(cl, constructorToCall); 295 } 296 297 /** 298 * Given a class, determines whether its superclass has 299 * any constructors that are accessible from the class. 300 * This is a special purpose method intended to do access 301 * checking for a serializable class and its superclasses 302 * up to, but not including, the first non-serializable 303 * superclass. This also implies that the superclass is 304 * always non-null, because a serializable class must be a 305 * class (not an interface) and Object is not serializable. 306 * 307 * @param cl the class from which access is checked 308 * @return whether the superclass has a constructor accessible from cl 309 */ 310 private boolean superHasAccessibleConstructor(Class<?> cl) { 311 Class<?> superCl = cl.getSuperclass(); 312 assert Serializable.class.isAssignableFrom(cl); 313 assert superCl != null; 314 if (packageEquals(cl, superCl)) { 315 // accessible if any non-private constructor is found 316 for (Constructor<?> ctor : superCl.getDeclaredConstructors()) { 317 if ((ctor.getModifiers() & Modifier.PRIVATE) == 0) { 318 return true; 319 } 320 } 321 if (Reflection.areNestMates(cl, superCl)) { 322 return true; 323 } 324 return false; 325 } else { 326 // sanity check to ensure the parent is protected or public 327 if ((superCl.getModifiers() & (Modifier.PROTECTED | Modifier.PUBLIC)) == 0) { 328 return false; 329 } 330 // accessible if any constructor is protected or public 331 for (Constructor<?> ctor : superCl.getDeclaredConstructors()) { 332 if ((ctor.getModifiers() & (Modifier.PROTECTED | Modifier.PUBLIC)) != 0) { 333 return true; 334 } 335 } 336 return false; 337 } 338 } 339 340 /** 341 * Returns a constructor that allocates an instance of cl and that then initializes 342 * the instance by calling the no-arg constructor of its first non-serializable 343 * superclass. This is specified in the Serialization Specification, section 3.1, 344 * in step 11 of the deserialization process. If cl is not serializable, returns 345 * cl's no-arg constructor. If no accessible constructor is found, or if the 346 * class hierarchy is somehow malformed (e.g., a serializable class has no 347 * superclass), null is returned. 348 * 349 * @param cl the class for which a constructor is to be found 350 * @return the generated constructor, or null if none is available 351 */ 352 public final Constructor<?> newConstructorForSerialization(Class<?> cl) { 353 if (cl.isValue()) { 354 throw new UnsupportedOperationException("newConstructorForSerialization does not support value classes"); 355 } 356 357 Class<?> initCl = cl; 358 while (Serializable.class.isAssignableFrom(initCl)) { 359 Class<?> prev = initCl; 360 if ((initCl = initCl.getSuperclass()) == null || 361 (!disableSerialConstructorChecks() && !superHasAccessibleConstructor(prev))) { 362 return null; 363 } 364 } 365 Constructor<?> constructorToCall; 366 try { 367 constructorToCall = initCl.getDeclaredConstructor(); 368 int mods = constructorToCall.getModifiers(); 369 if ((mods & Modifier.PRIVATE) != 0 || 370 ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 && 371 !packageEquals(cl, initCl))) { 372 return null; 373 } 374 } catch (NoSuchMethodException ex) { 375 return null; 376 } 377 return generateConstructor(cl, constructorToCall); 378 } 379 380 private final Constructor<?> generateConstructor(Class<?> cl, 381 Constructor<?> constructorToCall) { 382 383 Constructor<?> ctor = newConstructor(constructorToCall.getDeclaringClass(), 384 constructorToCall.getParameterTypes(), 385 constructorToCall.getExceptionTypes(), 386 constructorToCall.getModifiers(), 387 langReflectAccess.getConstructorSlot(constructorToCall), 388 langReflectAccess.getConstructorSignature(constructorToCall), 389 langReflectAccess.getConstructorAnnotations(constructorToCall), 390 langReflectAccess.getConstructorParameterAnnotations(constructorToCall)); 391 ConstructorAccessor acc; 392 if (useOldSerializableConstructor()) { 393 acc = new SerializationConstructorAccessorGenerator(). 394 generateSerializationConstructor(cl, 395 constructorToCall.getParameterTypes(), 396 constructorToCall.getModifiers(), 397 constructorToCall.getDeclaringClass()); 398 } else { 399 acc = MethodHandleAccessorFactory.newSerializableConstructorAccessor(cl, ctor); 400 } 401 setConstructorAccessor(ctor, acc); 402 ctor.setAccessible(true); 403 return ctor; 404 } 405 406 public final MethodHandle readObjectForSerialization(Class<?> cl) { 407 return findReadWriteObjectForSerialization(cl, "readObject", ObjectInputStream.class); 408 } 409 410 public final MethodHandle readObjectNoDataForSerialization(Class<?> cl) { 411 return findReadWriteObjectForSerialization(cl, "readObjectNoData", null); 412 } 413 414 public final MethodHandle writeObjectForSerialization(Class<?> cl) { 415 return findReadWriteObjectForSerialization(cl, "writeObject", ObjectOutputStream.class); 416 } 417 418 private final MethodHandle findReadWriteObjectForSerialization(Class<?> cl, 419 String methodName, 420 Class<?> streamClass) { 421 if (!Serializable.class.isAssignableFrom(cl)) { 422 return null; 423 } 424 425 try { 426 Method meth = streamClass == null ? cl.getDeclaredMethod(methodName) 427 : cl.getDeclaredMethod(methodName, streamClass); 428 int mods = meth.getModifiers(); 429 if (meth.getReturnType() != Void.TYPE || 430 Modifier.isStatic(mods) || 431 !Modifier.isPrivate(mods)) { 432 return null; 433 } 434 meth.setAccessible(true); 435 return MethodHandles.lookup().unreflect(meth); 436 } catch (NoSuchMethodException ex) { 437 return null; 438 } catch (IllegalAccessException ex1) { 439 throw new InternalError("Error", ex1); 440 } 441 } 442 443 /** 444 * Returns a MethodHandle for {@code writeReplace} on the serializable class 445 * or null if no match found. 446 * @param cl a serializable class 447 * @return the {@code writeReplace} MethodHandle or {@code null} if not found 448 */ 449 public final MethodHandle writeReplaceForSerialization(Class<?> cl) { 450 return getReplaceResolveForSerialization(cl, "writeReplace"); 451 } 452 453 /** 454 * Returns a MethodHandle for {@code readResolve} on the serializable class 455 * or null if no match found. 456 * @param cl a serializable class 457 * @return the {@code writeReplace} MethodHandle or {@code null} if not found 458 */ 459 public final MethodHandle readResolveForSerialization(Class<?> cl) { 460 return getReplaceResolveForSerialization(cl, "readResolve"); 461 } 462 463 /** 464 * Lookup readResolve or writeReplace on a class with specified 465 * signature constraints. 466 * @param cl a serializable class 467 * @param methodName the method name to find 468 * @return a MethodHandle for the method or {@code null} if not found or 469 * has the wrong signature. 470 */ 471 private MethodHandle getReplaceResolveForSerialization(Class<?> cl, 472 String methodName) { 473 if (!Serializable.class.isAssignableFrom(cl)) { 474 return null; 475 } 476 477 Class<?> defCl = cl; 478 while (defCl != null) { 479 try { 480 Method m = defCl.getDeclaredMethod(methodName); 481 if (m.getReturnType() != Object.class) { 482 return null; 483 } 484 int mods = m.getModifiers(); 485 if (Modifier.isStatic(mods) | Modifier.isAbstract(mods)) { 486 return null; 487 } else if (Modifier.isPublic(mods) | Modifier.isProtected(mods)) { 488 // fall through 489 } else if (Modifier.isPrivate(mods) && (cl != defCl)) { 490 return null; 491 } else if (!packageEquals(cl, defCl)) { 492 return null; 493 } 494 try { 495 // Normal return 496 m.setAccessible(true); 497 return MethodHandles.lookup().unreflect(m); 498 } catch (IllegalAccessException ex0) { 499 // setAccessible should prevent IAE 500 throw new InternalError("Error", ex0); 501 } 502 } catch (NoSuchMethodException ex) { 503 defCl = defCl.getSuperclass(); 504 } 505 } 506 return null; 507 } 508 509 /** 510 * Returns true if the given class defines a static initializer method, 511 * false otherwise. 512 */ 513 public final boolean hasStaticInitializerForSerialization(Class<?> cl) { 514 Method m = hasStaticInitializerMethod; 515 if (m == null) { 516 try { 517 m = ObjectStreamClass.class.getDeclaredMethod("hasStaticInitializer", 518 new Class<?>[]{Class.class}); 519 m.setAccessible(true); 520 hasStaticInitializerMethod = m; 521 } catch (NoSuchMethodException ex) { 522 throw new InternalError("No such method hasStaticInitializer on " 523 + ObjectStreamClass.class, ex); 524 } 525 } 526 try { 527 return (Boolean) m.invoke(null, cl); 528 } catch (InvocationTargetException | IllegalAccessException ex) { 529 throw new InternalError("Exception invoking hasStaticInitializer", ex); 530 } 531 } 532 533 /** 534 * Return the accessible constructor for OptionalDataException signaling eof. 535 * @return the eof constructor for OptionalDataException 536 */ 537 public final Constructor<OptionalDataException> newOptionalDataExceptionForSerialization() { 538 try { 539 Constructor<OptionalDataException> boolCtor = 540 OptionalDataException.class.getDeclaredConstructor(Boolean.TYPE); 541 boolCtor.setAccessible(true); 542 return boolCtor; 543 } catch (NoSuchMethodException ex) { 544 throw new InternalError("Constructor not found", ex); 545 } 546 } 547 548 //-------------------------------------------------------------------------- 549 // 550 // Internals only below this point 551 // 552 553 /* 554 * If -Djdk.reflect.useNativeAccessorOnly is set, use the native accessor only. 555 * For testing purpose only. 556 */ 557 static boolean useNativeAccessorOnly() { 558 return config().useNativeAccessorOnly; 559 } 560 561 static boolean useOldSerializableConstructor() { 562 return config().useOldSerializableConstructor; 563 } 564 565 private static boolean disableSerialConstructorChecks() { 566 return config().disableSerialConstructorChecks; 567 } 568 569 /** 570 * The configuration is lazily initialized after the module system is initialized. The 571 * default config would be used before the proper config is loaded. 572 * 573 * The static initializer of ReflectionFactory is run before the system properties are set up. 574 * The class initialization is caused by the class initialization of java.lang.reflect.Method 575 * (more properly, caused by the class initialization for java.lang.reflect.AccessibleObject) 576 * that happens very early VM startup, initPhase1. 577 */ 578 private static @Stable Config config; 579 580 private static final Config DEFAULT_CONFIG = new Config(false, // useNativeAccessorOnly 581 false, // useOldSerializeableConstructor 582 false); // disableSerialConstructorChecks 583 584 /** 585 * The configurations for the reflection factory. Configurable via 586 * system properties but only available after ReflectionFactory is 587 * loaded during early VM startup. 588 * 589 * Note that the default implementations of the object methods of 590 * this Config record (toString, equals, hashCode) use indy, 591 * which is available to use only after initPhase1. These methods 592 * are currently not called, but should they be needed, a workaround 593 * is to override them. 594 */ 595 private record Config(boolean useNativeAccessorOnly, 596 boolean useOldSerializableConstructor, 597 boolean disableSerialConstructorChecks) { 598 } 599 600 private static Config config() { 601 Config c = config; 602 if (c != null) { 603 return c; 604 } 605 606 // Always use the default configuration until the module system is initialized. 607 if (!VM.isModuleSystemInited()) { 608 return DEFAULT_CONFIG; 609 } 610 611 return config = loadConfig(); 612 } 613 614 private static Config loadConfig() { 615 assert VM.isModuleSystemInited(); 616 617 Properties props = GetPropertyAction.privilegedGetProperties(); 618 boolean useNativeAccessorOnly = 619 "true".equals(props.getProperty("jdk.reflect.useNativeAccessorOnly")); 620 boolean useOldSerializableConstructor = 621 "true".equals(props.getProperty("jdk.reflect.useOldSerializableConstructor")); 622 boolean disableSerialConstructorChecks = 623 "true".equals(props.getProperty("jdk.disableSerialConstructorChecks")); 624 625 return new Config(useNativeAccessorOnly, useOldSerializableConstructor, disableSerialConstructorChecks); 626 } 627 628 /** 629 * Returns true if classes are defined in the classloader and same package, false 630 * otherwise. 631 * @param cl1 a class 632 * @param cl2 another class 633 * @return true if the two classes are in the same classloader and package 634 */ 635 private static boolean packageEquals(Class<?> cl1, Class<?> cl2) { 636 assert !cl1.isArray() && !cl2.isArray(); 637 638 if (cl1 == cl2) { 639 return true; 640 } 641 642 return cl1.getClassLoader() == cl2.getClassLoader() && 643 cl1.getPackageName() == cl2.getPackageName(); 644 } 645 646 }