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