1 /*
2  * Copyright (c) 2001, 2020, 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.access.JavaLangReflectAccess;
47 import jdk.internal.access.SharedSecrets;
48 import jdk.internal.misc.VM;
49 import sun.reflect.misc.ReflectUtil;
50 import sun.security.action.GetPropertyAction;
51 import sun.security.util.SecurityConstants;
52 
53 /** <P> The master factory for all reflective objects, both those in
54     java.lang.reflect (Fields, Methods, Constructors) as well as their
55     delegates (FieldAccessors, MethodAccessors, ConstructorAccessors).
56     </P>
57 
58     <P> The methods in this class are extremely unsafe and can cause
59     subversion of both the language and the verifier. For this reason,
60     they are all instance methods, and access to the constructor of
61     this factory is guarded by a security check, in similar style to
62     {@link jdk.internal.misc.Unsafe}. </P>
63 */
64 
65 public class ReflectionFactory {
66 
67     private static boolean initted = false;
68     private static final ReflectionFactory soleInstance = new ReflectionFactory();
69 
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 
91     // true if deserialization constructor checking is disabled
92     private static boolean disableSerialConstructorChecks = false;
93 
94     private final JavaLangReflectAccess langReflectAccess;
ReflectionFactory()95     private ReflectionFactory() {
96         this.langReflectAccess = SharedSecrets.getJavaLangReflectAccess();
97     }
98 
99     /**
100      * A convenience class for acquiring the capability to instantiate
101      * reflective objects.  Use this instead of a raw call to {@link
102      * #getReflectionFactory} in order to avoid being limited by the
103      * permissions of your callers.
104      *
105      * <p>An instance of this class can be used as the argument of
106      * <code>AccessController.doPrivileged</code>.
107      */
108     public static final class GetReflectionFactoryAction
109         implements PrivilegedAction<ReflectionFactory> {
run()110         public ReflectionFactory run() {
111             return getReflectionFactory();
112         }
113     }
114 
115     /**
116      * Provides the caller with the capability to instantiate reflective
117      * objects.
118      *
119      * <p> First, if there is a security manager, its
120      * <code>checkPermission</code> method is called with a {@link
121      * java.lang.RuntimePermission} with target
122      * <code>"reflectionFactoryAccess"</code>.  This may result in a
123      * security exception.
124      *
125      * <p> The returned <code>ReflectionFactory</code> object should be
126      * carefully guarded by the caller, since it can be used to read and
127      * write private data and invoke private methods, as well as to load
128      * unverified bytecodes.  It must never be passed to untrusted code.
129      *
130      * @exception SecurityException if a security manager exists and its
131      *             <code>checkPermission</code> method doesn't allow
132      *             access to the RuntimePermission "reflectionFactoryAccess".  */
getReflectionFactory()133     public static ReflectionFactory getReflectionFactory() {
134         SecurityManager security = System.getSecurityManager();
135         if (security != null) {
136             security.checkPermission(
137                 SecurityConstants.REFLECTION_FACTORY_ACCESS_PERMISSION);
138         }
139         return soleInstance;
140     }
141 
142     /**
143      * Returns an alternate reflective Method instance for the given method
144      * intended for reflection to invoke, if present.
145      *
146      * A trusted method can define an alternate implementation for a method `foo`
147      * by defining a method named "reflected$foo" that will be invoked
148      * reflectively.
149      */
findMethodForReflection(Method method)150     private static Method findMethodForReflection(Method method) {
151         String altName = "reflected$" + method.getName();
152         try {
153            return method.getDeclaringClass()
154                         .getDeclaredMethod(altName, method.getParameterTypes());
155         } catch (NoSuchMethodException ex) {
156             return null;
157         }
158     }
159 
160     //--------------------------------------------------------------------------
161     //
162     // Routines used by java.lang.reflect
163     //
164     //
165 
166     /*
167      * Note: this routine can cause the declaring class for the field
168      * be initialized and therefore must not be called until the
169      * first get/set of this field.
170      * @param field the field
171      * @param override true if caller has overridden accessibility
172      */
newFieldAccessor(Field field, boolean override)173     public FieldAccessor newFieldAccessor(Field field, boolean override) {
174         checkInitted();
175 
176         Field root = langReflectAccess.getRoot(field);
177         if (root != null) {
178             // FieldAccessor will use the root unless the modifiers have
179             // been overridden
180             if (root.getModifiers() == field.getModifiers() || !override) {
181                 field = root;
182             }
183         }
184         boolean isFinal = Modifier.isFinal(field.getModifiers());
185         boolean isReadOnly = isFinal && (!override || langReflectAccess.isTrustedFinalField(field));
186         return UnsafeFieldAccessorFactory.newFieldAccessor(field, isReadOnly);
187     }
188 
newMethodAccessor(Method method)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 && !method.getDeclaringClass().isHidden()
206                 && !ReflectUtil.isVMAnonymousClass(method.getDeclaringClass())) {
207             return new MethodAccessorGenerator().
208                 generateMethod(method.getDeclaringClass(),
209                                method.getName(),
210                                method.getParameterTypes(),
211                                method.getReturnType(),
212                                method.getExceptionTypes(),
213                                method.getModifiers());
214         } else {
215             NativeMethodAccessorImpl acc =
216                 new NativeMethodAccessorImpl(method);
217             DelegatingMethodAccessorImpl res =
218                 new DelegatingMethodAccessorImpl(acc);
219             acc.setParent(res);
220             return res;
221         }
222     }
223 
newConstructorAccessor(Constructor<?> c)224     public ConstructorAccessor newConstructorAccessor(Constructor<?> c) {
225         checkInitted();
226 
227         Class<?> declaringClass = c.getDeclaringClass();
228         if (Modifier.isAbstract(declaringClass.getModifiers())) {
229             return new InstantiationExceptionConstructorAccessorImpl(null);
230         }
231         if (declaringClass == Class.class) {
232             return new InstantiationExceptionConstructorAccessorImpl
233                 ("Can not instantiate java.lang.Class");
234         }
235 
236         // use the root Constructor that will not cache caller class
237         Constructor<?> root = langReflectAccess.getRoot(c);
238         if (root != null) {
239             c = root;
240         }
241 
242         // Bootstrapping issue: since we use Class.newInstance() in
243         // the ConstructorAccessor generation process, we have to
244         // break the cycle here.
245         if (Reflection.isSubclassOf(declaringClass,
246                                     ConstructorAccessorImpl.class)) {
247             return new BootstrapConstructorAccessorImpl(c);
248         }
249 
250         if (noInflation && !c.getDeclaringClass().isHidden()
251                 && !ReflectUtil.isVMAnonymousClass(c.getDeclaringClass())) {
252             return new MethodAccessorGenerator().
253                 generateConstructor(c.getDeclaringClass(),
254                                     c.getParameterTypes(),
255                                     c.getExceptionTypes(),
256                                     c.getModifiers());
257         } else {
258             NativeConstructorAccessorImpl acc =
259                 new NativeConstructorAccessorImpl(c);
260             DelegatingConstructorAccessorImpl res =
261                 new DelegatingConstructorAccessorImpl(acc);
262             acc.setParent(res);
263             return res;
264         }
265     }
266 
267     //--------------------------------------------------------------------------
268     //
269     // Routines used by java.lang
270     //
271     //
272 
273     /** Creates a new java.lang.reflect.Constructor. Access checks as
274         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)275     public Constructor<?> newConstructor(Class<?> declaringClass,
276                                          Class<?>[] parameterTypes,
277                                          Class<?>[] checkedExceptions,
278                                          int modifiers,
279                                          int slot,
280                                          String signature,
281                                          byte[] annotations,
282                                          byte[] parameterAnnotations)
283     {
284         return langReflectAccess.newConstructor(declaringClass,
285                                                 parameterTypes,
286                                                 checkedExceptions,
287                                                 modifiers,
288                                                 slot,
289                                                 signature,
290                                                 annotations,
291                                                 parameterAnnotations);
292     }
293 
294     /** Gets the ConstructorAccessor object for a
295         java.lang.reflect.Constructor */
getConstructorAccessor(Constructor<?> c)296     public ConstructorAccessor getConstructorAccessor(Constructor<?> c) {
297         return langReflectAccess.getConstructorAccessor(c);
298     }
299 
300     /** Sets the ConstructorAccessor object for a
301         java.lang.reflect.Constructor */
setConstructorAccessor(Constructor<?> c, ConstructorAccessor accessor)302     public void setConstructorAccessor(Constructor<?> c,
303                                        ConstructorAccessor accessor)
304     {
305         langReflectAccess.setConstructorAccessor(c, accessor);
306     }
307 
308     /** Makes a copy of the passed method. The returned method is a
309         "child" of the passed one; see the comments in Method.java for
310         details. */
copyMethod(Method arg)311     public Method copyMethod(Method arg) {
312         return langReflectAccess.copyMethod(arg);
313     }
314 
315     /** Makes a copy of the passed method. The returned method is NOT
316      * a "child" but a "sibling" of the Method in arg. Should only be
317      * used on non-root methods. */
leafCopyMethod(Method arg)318     public Method leafCopyMethod(Method arg) {
319         return langReflectAccess.leafCopyMethod(arg);
320     }
321 
322 
323     /** Makes a copy of the passed field. The returned field is a
324         "child" of the passed one; see the comments in Field.java for
325         details. */
copyField(Field arg)326     public Field copyField(Field arg) {
327         return langReflectAccess.copyField(arg);
328     }
329 
330     /** Makes a copy of the passed constructor. The returned
331         constructor is a "child" of the passed one; see the comments
332         in Constructor.java for details. */
copyConstructor(Constructor<T> arg)333     public <T> Constructor<T> copyConstructor(Constructor<T> arg) {
334         return langReflectAccess.copyConstructor(arg);
335     }
336 
337     /** Gets the byte[] that encodes TypeAnnotations on an executable.
338      */
getExecutableTypeAnnotationBytes(Executable ex)339     public byte[] getExecutableTypeAnnotationBytes(Executable ex) {
340         return langReflectAccess.getExecutableTypeAnnotationBytes(ex);
341     }
342 
getExecutableSharedParameterTypes(Executable ex)343     public Class<?>[] getExecutableSharedParameterTypes(Executable ex) {
344         return langReflectAccess.getExecutableSharedParameterTypes(ex);
345     }
346 
newInstance(Constructor<T> ctor, Object[] args, Class<?> caller)347     public <T> T newInstance(Constructor<T> ctor, Object[] args, Class<?> caller)
348         throws IllegalAccessException, InstantiationException, InvocationTargetException
349     {
350         return langReflectAccess.newInstance(ctor, args, caller);
351     }
352 
353     //--------------------------------------------------------------------------
354     //
355     // Routines used by serialization
356     //
357     //
358 
newConstructorForExternalization(Class<?> cl)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 
newConstructorForSerialization(Class<?> cl, Constructor<?> constructorToCall)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     /**
383      * Given a class, determines whether its superclass has
384      * any constructors that are accessible from the class.
385      * This is a special purpose method intended to do access
386      * checking for a serializable class and its superclasses
387      * up to, but not including, the first non-serializable
388      * superclass. This also implies that the superclass is
389      * always non-null, because a serializable class must be a
390      * class (not an interface) and Object is not serializable.
391      *
392      * @param cl the class from which access is checked
393      * @return whether the superclass has a constructor accessible from cl
394      */
superHasAccessibleConstructor(Class<?> cl)395     private boolean superHasAccessibleConstructor(Class<?> cl) {
396         Class<?> superCl = cl.getSuperclass();
397         assert Serializable.class.isAssignableFrom(cl);
398         assert superCl != null;
399         if (packageEquals(cl, superCl)) {
400             // accessible if any non-private constructor is found
401             for (Constructor<?> ctor : superCl.getDeclaredConstructors()) {
402                 if ((ctor.getModifiers() & Modifier.PRIVATE) == 0) {
403                     return true;
404                 }
405             }
406             if (Reflection.areNestMates(cl, superCl)) {
407                 return true;
408             }
409             return false;
410         } else {
411             // sanity check to ensure the parent is protected or public
412             if ((superCl.getModifiers() & (Modifier.PROTECTED | Modifier.PUBLIC)) == 0) {
413                 return false;
414             }
415             // accessible if any constructor is protected or public
416             for (Constructor<?> ctor : superCl.getDeclaredConstructors()) {
417                 if ((ctor.getModifiers() & (Modifier.PROTECTED | Modifier.PUBLIC)) != 0) {
418                     return true;
419                 }
420             }
421             return false;
422         }
423     }
424 
425     /**
426      * Returns a constructor that allocates an instance of cl and that then initializes
427      * the instance by calling the no-arg constructor of its first non-serializable
428      * superclass. This is specified in the Serialization Specification, section 3.1,
429      * in step 11 of the deserialization process. If cl is not serializable, returns
430      * cl's no-arg constructor. If no accessible constructor is found, or if the
431      * class hierarchy is somehow malformed (e.g., a serializable class has no
432      * superclass), null is returned.
433      *
434      * @param cl the class for which a constructor is to be found
435      * @return the generated constructor, or null if none is available
436      */
newConstructorForSerialization(Class<?> cl)437     public final Constructor<?> newConstructorForSerialization(Class<?> cl) {
438         Class<?> initCl = cl;
439         while (Serializable.class.isAssignableFrom(initCl)) {
440             Class<?> prev = initCl;
441             if ((initCl = initCl.getSuperclass()) == null ||
442                 (!disableSerialConstructorChecks && !superHasAccessibleConstructor(prev))) {
443                 return null;
444             }
445         }
446         Constructor<?> constructorToCall;
447         try {
448             constructorToCall = initCl.getDeclaredConstructor();
449             int mods = constructorToCall.getModifiers();
450             if ((mods & Modifier.PRIVATE) != 0 ||
451                     ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 &&
452                             !packageEquals(cl, initCl))) {
453                 return null;
454             }
455         } catch (NoSuchMethodException ex) {
456             return null;
457         }
458         return generateConstructor(cl, constructorToCall);
459     }
460 
generateConstructor(Class<?> cl, Constructor<?> constructorToCall)461     private final Constructor<?> generateConstructor(Class<?> cl,
462                                                      Constructor<?> constructorToCall) {
463 
464 
465         ConstructorAccessor acc = new MethodAccessorGenerator().
466             generateSerializationConstructor(cl,
467                                              constructorToCall.getParameterTypes(),
468                                              constructorToCall.getExceptionTypes(),
469                                              constructorToCall.getModifiers(),
470                                              constructorToCall.getDeclaringClass());
471         Constructor<?> c = newConstructor(constructorToCall.getDeclaringClass(),
472                                           constructorToCall.getParameterTypes(),
473                                           constructorToCall.getExceptionTypes(),
474                                           constructorToCall.getModifiers(),
475                                           langReflectAccess.
476                                           getConstructorSlot(constructorToCall),
477                                           langReflectAccess.
478                                           getConstructorSignature(constructorToCall),
479                                           langReflectAccess.
480                                           getConstructorAnnotations(constructorToCall),
481                                           langReflectAccess.
482                                           getConstructorParameterAnnotations(constructorToCall));
483         setConstructorAccessor(c, acc);
484         c.setAccessible(true);
485         return c;
486     }
487 
readObjectForSerialization(Class<?> cl)488     public final MethodHandle readObjectForSerialization(Class<?> cl) {
489         return findReadWriteObjectForSerialization(cl, "readObject", ObjectInputStream.class);
490     }
491 
readObjectNoDataForSerialization(Class<?> cl)492     public final MethodHandle readObjectNoDataForSerialization(Class<?> cl) {
493         return findReadWriteObjectForSerialization(cl, "readObjectNoData", ObjectInputStream.class);
494     }
495 
writeObjectForSerialization(Class<?> cl)496     public final MethodHandle writeObjectForSerialization(Class<?> cl) {
497         return findReadWriteObjectForSerialization(cl, "writeObject", ObjectOutputStream.class);
498     }
499 
findReadWriteObjectForSerialization(Class<?> cl, String methodName, Class<?> streamClass)500     private final MethodHandle findReadWriteObjectForSerialization(Class<?> cl,
501                                                                    String methodName,
502                                                                    Class<?> streamClass) {
503         if (!Serializable.class.isAssignableFrom(cl)) {
504             return null;
505         }
506 
507         try {
508             Method meth = cl.getDeclaredMethod(methodName, streamClass);
509             int mods = meth.getModifiers();
510             if (meth.getReturnType() != Void.TYPE ||
511                     Modifier.isStatic(mods) ||
512                     !Modifier.isPrivate(mods)) {
513                 return null;
514             }
515             meth.setAccessible(true);
516             return MethodHandles.lookup().unreflect(meth);
517         } catch (NoSuchMethodException ex) {
518             return null;
519         } catch (IllegalAccessException ex1) {
520             throw new InternalError("Error", ex1);
521         }
522     }
523 
524     /**
525      * Returns a MethodHandle for {@code writeReplace} on the serializable class
526      * or null if no match found.
527      * @param cl a serializable class
528      * @returnss the {@code writeReplace} MethodHandle or {@code null} if not found
529      */
writeReplaceForSerialization(Class<?> cl)530     public final MethodHandle writeReplaceForSerialization(Class<?> cl) {
531         return getReplaceResolveForSerialization(cl, "writeReplace");
532     }
533 
534     /**
535      * Returns a MethodHandle for {@code readResolve} on the serializable class
536      * or null if no match found.
537      * @param cl a serializable class
538      * @returns the {@code writeReplace} MethodHandle or {@code null} if not found
539      */
readResolveForSerialization(Class<?> cl)540     public final MethodHandle readResolveForSerialization(Class<?> cl) {
541         return getReplaceResolveForSerialization(cl, "readResolve");
542     }
543 
544     /**
545      * Lookup readResolve or writeReplace on a class with specified
546      * signature constraints.
547      * @param cl a serializable class
548      * @param methodName the method name to find
549      * @returns a MethodHandle for the method or {@code null} if not found or
550      *       has the wrong signature.
551      */
getReplaceResolveForSerialization(Class<?> cl, String methodName)552     private MethodHandle getReplaceResolveForSerialization(Class<?> cl,
553                                                            String methodName) {
554         if (!Serializable.class.isAssignableFrom(cl)) {
555             return null;
556         }
557 
558         Class<?> defCl = cl;
559         while (defCl != null) {
560             try {
561                 Method m = defCl.getDeclaredMethod(methodName);
562                 if (m.getReturnType() != Object.class) {
563                     return null;
564                 }
565                 int mods = m.getModifiers();
566                 if (Modifier.isStatic(mods) | Modifier.isAbstract(mods)) {
567                     return null;
568                 } else if (Modifier.isPublic(mods) | Modifier.isProtected(mods)) {
569                     // fall through
570                 } else if (Modifier.isPrivate(mods) && (cl != defCl)) {
571                     return null;
572                 } else if (!packageEquals(cl, defCl)) {
573                     return null;
574                 }
575                 try {
576                     // Normal return
577                     m.setAccessible(true);
578                     return MethodHandles.lookup().unreflect(m);
579                 } catch (IllegalAccessException ex0) {
580                     // setAccessible should prevent IAE
581                     throw new InternalError("Error", ex0);
582                 }
583             } catch (NoSuchMethodException ex) {
584                 defCl = defCl.getSuperclass();
585             }
586         }
587         return null;
588     }
589 
590     /**
591      * Returns true if the given class defines a static initializer method,
592      * false otherwise.
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      * Return the accessible constructor for OptionalDataException signaling eof.
616      * @returns the eof constructor for OptionalDataException
617      */
newOptionalDataExceptionForSerialization()618     public final Constructor<OptionalDataException> newOptionalDataExceptionForSerialization() {
619         try {
620             Constructor<OptionalDataException> boolCtor =
621                     OptionalDataException.class.getDeclaredConstructor(Boolean.TYPE);
622             boolCtor.setAccessible(true);
623             return boolCtor;
624         } catch (NoSuchMethodException ex) {
625             throw new InternalError("Constructor not found", ex);
626         }
627     }
628 
629     //--------------------------------------------------------------------------
630     //
631     // Internals only below this point
632     //
633 
inflationThreshold()634     static int inflationThreshold() {
635         return inflationThreshold;
636     }
637 
638     /** We have to defer full initialization of this class until after
639         the static initializer is run since java.lang.reflect.Method's
640         static initializer (more properly, that for
641         java.lang.reflect.AccessibleObject) causes this class's to be
642         run, before the system properties are set up. */
checkInitted()643     private static void checkInitted() {
644         if (initted) return;
645 
646         // Defer initialization until module system is initialized so as
647         // to avoid inflation and spinning bytecode in unnamed modules
648         // during early startup.
649         if (!VM.isModuleSystemInited()) {
650             return;
651         }
652 
653         Properties props = GetPropertyAction.privilegedGetProperties();
654         String val = props.getProperty("sun.reflect.noInflation");
655         if (val != null && val.equals("true")) {
656             noInflation = true;
657         }
658 
659         val = props.getProperty("sun.reflect.inflationThreshold");
660         if (val != null) {
661             try {
662                 inflationThreshold = Integer.parseInt(val);
663             } catch (NumberFormatException e) {
664                 throw new RuntimeException("Unable to parse property sun.reflect.inflationThreshold", e);
665             }
666         }
667 
668         disableSerialConstructorChecks =
669             "true".equals(props.getProperty("jdk.disableSerialConstructorChecks"));
670 
671         initted = true;
672     }
673 
674     /**
675      * Returns true if classes are defined in the classloader and same package, false
676      * otherwise.
677      * @param cl1 a class
678      * @param cl2 another class
679      * @returns true if the two classes are in the same classloader and package
680      */
packageEquals(Class<?> cl1, Class<?> cl2)681     private static boolean packageEquals(Class<?> cl1, Class<?> cl2) {
682         assert !cl1.isArray() && !cl2.isArray();
683 
684         if (cl1 == cl2) {
685             return true;
686         }
687 
688         return cl1.getClassLoader() == cl2.getClassLoader() &&
689                 Objects.equals(cl1.getPackageName(), cl2.getPackageName());
690     }
691 
692 }
693