1 /*
2  * Copyright (c) 2001, 2019, 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 
ReflectionFactory()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> {
run()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".  */
getReflectionFactory()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      */
findMethodForReflection(Method method)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 */
setLangReflectAccess(LangReflectAccess access)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      */
newFieldAccessor(Field field, boolean override)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 
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 && !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 
newConstructorAccessor(Constructor<?> c)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. */
newField(Class<?> declaringClass, String name, Class<?> type, int modifiers, int slot, String signature, byte[] annotations)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. */
newMethod(Class<?> declaringClass, String name, Class<?>[] parameterTypes, Class<?> returnType, Class<?>[] checkedExceptions, int modifiers, int slot, String signature, byte[] annotations, byte[] parameterAnnotations, byte[] annotationDefault)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. */
newConstructor(Class<?> declaringClass, Class<?>[] parameterTypes, Class<?>[] checkedExceptions, int modifiers, int slot, String signature, byte[] annotations, byte[] parameterAnnotations)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 */
getMethodAccessor(Method m)339     public MethodAccessor getMethodAccessor(Method m) {
340         return langReflectAccess().getMethodAccessor(m);
341     }
342 
343     /** Sets the MethodAccessor object for a java.lang.reflect.Method */
setMethodAccessor(Method m, MethodAccessor accessor)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 */
getConstructorAccessor(Constructor<?> c)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 */
setConstructorAccessor(Constructor<?> c, ConstructorAccessor accessor)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. */
copyMethod(Method arg)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. */
leafCopyMethod(Method arg)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. */
copyField(Field arg)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. */
copyConstructor(Constructor<T> arg)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      */
getExecutableTypeAnnotationBytes(Executable ex)393     public byte[] getExecutableTypeAnnotationBytes(Executable ex) {
394         return langReflectAccess().getExecutableTypeAnnotationBytes(ex);
395     }
396 
getExecutableSharedParameterTypes(Executable ex)397     public Class<?>[] getExecutableSharedParameterTypes(Executable ex) {
398         return langReflectAccess().getExecutableSharedParameterTypes(ex);
399     }
400 
newInstance(Constructor<T> ctor, Object[] args, Class<?> caller)401     public <T> T newInstance(Constructor<T> ctor, Object[] args, Class<?> caller)
402         throws IllegalAccessException, InstantiationException, InvocationTargetException
403     {
404         return langReflectAccess().newInstance(ctor, args, caller);
405     }
406 
407     //--------------------------------------------------------------------------
408     //
409     // Routines used by serialization
410     //
411     //
412 
newConstructorForExternalization(Class<?> cl)413     public final Constructor<?> newConstructorForExternalization(Class<?> cl) {
414         if (!Externalizable.class.isAssignableFrom(cl)) {
415             return null;
416         }
417         try {
418             Constructor<?> cons = cl.getConstructor();
419             cons.setAccessible(true);
420             return cons;
421         } catch (NoSuchMethodException ex) {
422             return null;
423         }
424     }
425 
newConstructorForSerialization(Class<?> cl, Constructor<?> constructorToCall)426     public final Constructor<?> newConstructorForSerialization(Class<?> cl,
427                                                                Constructor<?> constructorToCall)
428     {
429         if (constructorToCall.getDeclaringClass() == cl) {
430             constructorToCall.setAccessible(true);
431             return constructorToCall;
432         }
433         return generateConstructor(cl, constructorToCall);
434     }
435 
436     /**
437      * Given a class, determines whether its superclass has
438      * any constructors that are accessible from the class.
439      * This is a special purpose method intended to do access
440      * checking for a serializable class and its superclasses
441      * up to, but not including, the first non-serializable
442      * superclass. This also implies that the superclass is
443      * always non-null, because a serializable class must be a
444      * class (not an interface) and Object is not serializable.
445      *
446      * @param cl the class from which access is checked
447      * @return whether the superclass has a constructor accessible from cl
448      */
superHasAccessibleConstructor(Class<?> cl)449     private boolean superHasAccessibleConstructor(Class<?> cl) {
450         Class<?> superCl = cl.getSuperclass();
451         assert Serializable.class.isAssignableFrom(cl);
452         assert superCl != null;
453         if (packageEquals(cl, superCl)) {
454             // accessible if any non-private constructor is found
455             for (Constructor<?> ctor : superCl.getDeclaredConstructors()) {
456                 if ((ctor.getModifiers() & Modifier.PRIVATE) == 0) {
457                     return true;
458                 }
459             }
460             if (Reflection.areNestMates(cl, superCl)) {
461                 return true;
462             }
463             return false;
464         } else {
465             // sanity check to ensure the parent is protected or public
466             if ((superCl.getModifiers() & (Modifier.PROTECTED | Modifier.PUBLIC)) == 0) {
467                 return false;
468             }
469             // accessible if any constructor is protected or public
470             for (Constructor<?> ctor : superCl.getDeclaredConstructors()) {
471                 if ((ctor.getModifiers() & (Modifier.PROTECTED | Modifier.PUBLIC)) != 0) {
472                     return true;
473                 }
474             }
475             return false;
476         }
477     }
478 
479     /**
480      * Returns a constructor that allocates an instance of cl and that then initializes
481      * the instance by calling the no-arg constructor of its first non-serializable
482      * superclass. This is specified in the Serialization Specification, section 3.1,
483      * in step 11 of the deserialization process. If cl is not serializable, returns
484      * cl's no-arg constructor. If no accessible constructor is found, or if the
485      * class hierarchy is somehow malformed (e.g., a serializable class has no
486      * superclass), null is returned.
487      *
488      * @param cl the class for which a constructor is to be found
489      * @return the generated constructor, or null if none is available
490      */
newConstructorForSerialization(Class<?> cl)491     public final Constructor<?> newConstructorForSerialization(Class<?> cl) {
492         Class<?> initCl = cl;
493         while (Serializable.class.isAssignableFrom(initCl)) {
494             Class<?> prev = initCl;
495             if ((initCl = initCl.getSuperclass()) == null ||
496                 (!disableSerialConstructorChecks && !superHasAccessibleConstructor(prev))) {
497                 return null;
498             }
499         }
500         Constructor<?> constructorToCall;
501         try {
502             constructorToCall = initCl.getDeclaredConstructor();
503             int mods = constructorToCall.getModifiers();
504             if ((mods & Modifier.PRIVATE) != 0 ||
505                     ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 &&
506                             !packageEquals(cl, initCl))) {
507                 return null;
508             }
509         } catch (NoSuchMethodException ex) {
510             return null;
511         }
512         return generateConstructor(cl, constructorToCall);
513     }
514 
generateConstructor(Class<?> cl, Constructor<?> constructorToCall)515     private final Constructor<?> generateConstructor(Class<?> cl,
516                                                      Constructor<?> constructorToCall) {
517 
518 
519         ConstructorAccessor acc = new MethodAccessorGenerator().
520             generateSerializationConstructor(cl,
521                                              constructorToCall.getParameterTypes(),
522                                              constructorToCall.getExceptionTypes(),
523                                              constructorToCall.getModifiers(),
524                                              constructorToCall.getDeclaringClass());
525         Constructor<?> c = newConstructor(constructorToCall.getDeclaringClass(),
526                                           constructorToCall.getParameterTypes(),
527                                           constructorToCall.getExceptionTypes(),
528                                           constructorToCall.getModifiers(),
529                                           langReflectAccess().
530                                           getConstructorSlot(constructorToCall),
531                                           langReflectAccess().
532                                           getConstructorSignature(constructorToCall),
533                                           langReflectAccess().
534                                           getConstructorAnnotations(constructorToCall),
535                                           langReflectAccess().
536                                           getConstructorParameterAnnotations(constructorToCall));
537         setConstructorAccessor(c, acc);
538         c.setAccessible(true);
539         return c;
540     }
541 
readObjectForSerialization(Class<?> cl)542     public final MethodHandle readObjectForSerialization(Class<?> cl) {
543         return findReadWriteObjectForSerialization(cl, "readObject", ObjectInputStream.class);
544     }
545 
readObjectNoDataForSerialization(Class<?> cl)546     public final MethodHandle readObjectNoDataForSerialization(Class<?> cl) {
547         return findReadWriteObjectForSerialization(cl, "readObjectNoData", ObjectInputStream.class);
548     }
549 
writeObjectForSerialization(Class<?> cl)550     public final MethodHandle writeObjectForSerialization(Class<?> cl) {
551         return findReadWriteObjectForSerialization(cl, "writeObject", ObjectOutputStream.class);
552     }
553 
findReadWriteObjectForSerialization(Class<?> cl, String methodName, Class<?> streamClass)554     private final MethodHandle findReadWriteObjectForSerialization(Class<?> cl,
555                                                                    String methodName,
556                                                                    Class<?> streamClass) {
557         if (!Serializable.class.isAssignableFrom(cl)) {
558             return null;
559         }
560 
561         try {
562             Method meth = cl.getDeclaredMethod(methodName, streamClass);
563             int mods = meth.getModifiers();
564             if (meth.getReturnType() != Void.TYPE ||
565                     Modifier.isStatic(mods) ||
566                     !Modifier.isPrivate(mods)) {
567                 return null;
568             }
569             meth.setAccessible(true);
570             return MethodHandles.lookup().unreflect(meth);
571         } catch (NoSuchMethodException ex) {
572             return null;
573         } catch (IllegalAccessException ex1) {
574             throw new InternalError("Error", ex1);
575         }
576     }
577 
578     /**
579      * Returns a MethodHandle for {@code writeReplace} on the serializable class
580      * or null if no match found.
581      * @param cl a serializable class
582      * @returnss the {@code writeReplace} MethodHandle or {@code null} if not found
583      */
writeReplaceForSerialization(Class<?> cl)584     public final MethodHandle writeReplaceForSerialization(Class<?> cl) {
585         return getReplaceResolveForSerialization(cl, "writeReplace");
586     }
587 
588     /**
589      * Returns a MethodHandle for {@code readResolve} on the serializable class
590      * or null if no match found.
591      * @param cl a serializable class
592      * @returns the {@code writeReplace} MethodHandle or {@code null} if not found
593      */
readResolveForSerialization(Class<?> cl)594     public final MethodHandle readResolveForSerialization(Class<?> cl) {
595         return getReplaceResolveForSerialization(cl, "readResolve");
596     }
597 
598     /**
599      * Lookup readResolve or writeReplace on a class with specified
600      * signature constraints.
601      * @param cl a serializable class
602      * @param methodName the method name to find
603      * @returns a MethodHandle for the method or {@code null} if not found or
604      *       has the wrong signature.
605      */
getReplaceResolveForSerialization(Class<?> cl, String methodName)606     private MethodHandle getReplaceResolveForSerialization(Class<?> cl,
607                                                            String methodName) {
608         if (!Serializable.class.isAssignableFrom(cl)) {
609             return null;
610         }
611 
612         Class<?> defCl = cl;
613         while (defCl != null) {
614             try {
615                 Method m = defCl.getDeclaredMethod(methodName);
616                 if (m.getReturnType() != Object.class) {
617                     return null;
618                 }
619                 int mods = m.getModifiers();
620                 if (Modifier.isStatic(mods) | Modifier.isAbstract(mods)) {
621                     return null;
622                 } else if (Modifier.isPublic(mods) | Modifier.isProtected(mods)) {
623                     // fall through
624                 } else if (Modifier.isPrivate(mods) && (cl != defCl)) {
625                     return null;
626                 } else if (!packageEquals(cl, defCl)) {
627                     return null;
628                 }
629                 try {
630                     // Normal return
631                     m.setAccessible(true);
632                     return MethodHandles.lookup().unreflect(m);
633                 } catch (IllegalAccessException ex0) {
634                     // setAccessible should prevent IAE
635                     throw new InternalError("Error", ex0);
636                 }
637             } catch (NoSuchMethodException ex) {
638                 defCl = defCl.getSuperclass();
639             }
640         }
641         return null;
642     }
643 
644     /**
645      * Returns true if the given class defines a static initializer method,
646      * false otherwise.
647      */
hasStaticInitializerForSerialization(Class<?> cl)648     public final boolean hasStaticInitializerForSerialization(Class<?> cl) {
649         Method m = hasStaticInitializerMethod;
650         if (m == null) {
651             try {
652                 m = ObjectStreamClass.class.getDeclaredMethod("hasStaticInitializer",
653                         new Class<?>[]{Class.class});
654                 m.setAccessible(true);
655                 hasStaticInitializerMethod = m;
656             } catch (NoSuchMethodException ex) {
657                 throw new InternalError("No such method hasStaticInitializer on "
658                         + ObjectStreamClass.class, ex);
659             }
660         }
661         try {
662             return (Boolean) m.invoke(null, cl);
663         } catch (InvocationTargetException | IllegalAccessException ex) {
664             throw new InternalError("Exception invoking hasStaticInitializer", ex);
665         }
666     }
667 
668     /**
669      * Return the accessible constructor for OptionalDataException signaling eof.
670      * @returns the eof constructor for OptionalDataException
671      */
newOptionalDataExceptionForSerialization()672     public final Constructor<OptionalDataException> newOptionalDataExceptionForSerialization() {
673         try {
674             Constructor<OptionalDataException> boolCtor =
675                     OptionalDataException.class.getDeclaredConstructor(Boolean.TYPE);
676             boolCtor.setAccessible(true);
677             return boolCtor;
678         } catch (NoSuchMethodException ex) {
679             throw new InternalError("Constructor not found", ex);
680         }
681     }
682 
683     //--------------------------------------------------------------------------
684     //
685     // Internals only below this point
686     //
687 
inflationThreshold()688     static int inflationThreshold() {
689         return inflationThreshold;
690     }
691 
692     /** We have to defer full initialization of this class until after
693         the static initializer is run since java.lang.reflect.Method's
694         static initializer (more properly, that for
695         java.lang.reflect.AccessibleObject) causes this class's to be
696         run, before the system properties are set up. */
checkInitted()697     private static void checkInitted() {
698         if (initted) return;
699 
700         // Defer initialization until module system is initialized so as
701         // to avoid inflation and spinning bytecode in unnamed modules
702         // during early startup.
703         if (!VM.isModuleSystemInited()) {
704             return;
705         }
706 
707         Properties props = GetPropertyAction.privilegedGetProperties();
708         String val = props.getProperty("sun.reflect.noInflation");
709         if (val != null && val.equals("true")) {
710             noInflation = true;
711         }
712 
713         val = props.getProperty("sun.reflect.inflationThreshold");
714         if (val != null) {
715             try {
716                 inflationThreshold = Integer.parseInt(val);
717             } catch (NumberFormatException e) {
718                 throw new RuntimeException("Unable to parse property sun.reflect.inflationThreshold", e);
719             }
720         }
721 
722         disableSerialConstructorChecks =
723             "true".equals(props.getProperty("jdk.disableSerialConstructorChecks"));
724 
725         initted = true;
726     }
727 
langReflectAccess()728     private static LangReflectAccess langReflectAccess() {
729         if (langReflectAccess == null) {
730             // Call a static method to get class java.lang.reflect.Modifier
731             // initialized. Its static initializer will cause
732             // setLangReflectAccess() to be called from the context of the
733             // java.lang.reflect package.
734             Modifier.isPublic(Modifier.PUBLIC);
735         }
736         return langReflectAccess;
737     }
738 
739     /**
740      * Returns true if classes are defined in the classloader and same package, false
741      * otherwise.
742      * @param cl1 a class
743      * @param cl2 another class
744      * @returns true if the two classes are in the same classloader and package
745      */
packageEquals(Class<?> cl1, Class<?> cl2)746     private static boolean packageEquals(Class<?> cl1, Class<?> cl2) {
747         assert !cl1.isArray() && !cl2.isArray();
748 
749         if (cl1 == cl2) {
750             return true;
751         }
752 
753         return cl1.getClassLoader() == cl2.getClassLoader() &&
754                 Objects.equals(cl1.getPackageName(), cl2.getPackageName());
755     }
756 
757 }
758