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