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