< prev index next >

src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java

Print this page

 68     /* Method for static class initializer <clinit>, or null */
 69     private static volatile Method hasStaticInitializerMethod;
 70 
 71     //
 72     // "Inflation" mechanism. Loading bytecodes to implement
 73     // Method.invoke() and Constructor.newInstance() currently costs
 74     // 3-4x more than an invocation via native code for the first
 75     // invocation (though subsequent invocations have been benchmarked
 76     // to be over 20x faster). Unfortunately this cost increases
 77     // startup time for certain applications that use reflection
 78     // intensively (but only once per class) to bootstrap themselves.
 79     // To avoid this penalty we reuse the existing JVM entry points
 80     // for the first few invocations of Methods and Constructors and
 81     // then switch to the bytecode-based implementations.
 82     //
 83     // Package-private to be accessible to NativeMethodAccessorImpl
 84     // and NativeConstructorAccessorImpl
 85     private static boolean noInflation        = false;
 86     private static int     inflationThreshold = 15;
 87 









 88     // true if deserialization constructor checking is disabled
 89     private static boolean disableSerialConstructorChecks = false;
 90 
 91     private final JavaLangReflectAccess langReflectAccess;
 92     private ReflectionFactory() {
 93         this.langReflectAccess = SharedSecrets.getJavaLangReflectAccess();
 94     }
 95 
 96     /**
 97      * A convenience class for acquiring the capability to instantiate
 98      * reflective objects.  Use this instead of a raw call to {@link
 99      * #getReflectionFactory} in order to avoid being limited by the
100      * permissions of your callers.
101      *
102      * <p>An instance of this class can be used as the argument of
103      * <code>AccessController.doPrivileged</code>.
104      */
105     public static final class GetReflectionFactoryAction
106         implements PrivilegedAction<ReflectionFactory> {
107         public ReflectionFactory run() {

120      * security exception.
121      *
122      * <p> The returned <code>ReflectionFactory</code> object should be
123      * carefully guarded by the caller, since it can be used to read and
124      * write private data and invoke private methods, as well as to load
125      * unverified bytecodes.  It must never be passed to untrusted code.
126      *
127      * @exception SecurityException if a security manager exists and its
128      *             <code>checkPermission</code> method doesn't allow
129      *             access to the RuntimePermission "reflectionFactoryAccess".  */
130     public static ReflectionFactory getReflectionFactory() {
131         @SuppressWarnings("removal")
132         SecurityManager security = System.getSecurityManager();
133         if (security != null) {
134             security.checkPermission(
135                 SecurityConstants.REFLECTION_FACTORY_ACCESS_PERMISSION);
136         }
137         return soleInstance;
138     }
139 
140     /**
141      * Returns an alternate reflective Method instance for the given method
142      * intended for reflection to invoke, if present.
143      *
144      * A trusted method can define an alternate implementation for a method `foo`
145      * by defining a method named "reflected$foo" that will be invoked
146      * reflectively.
147      */
148     private static Method findMethodForReflection(Method method) {
149         String altName = "reflected$" + method.getName();
150         try {
151            return method.getDeclaringClass()
152                         .getDeclaredMethod(altName, method.getParameterTypes());
153         } catch (NoSuchMethodException ex) {
154             return null;
155         }
156     }
157 
158     //--------------------------------------------------------------------------
159     //
160     // Routines used by java.lang.reflect
161     //
162     //
163 
164     /*
165      * Note: this routine can cause the declaring class for the field
166      * be initialized and therefore must not be called until the
167      * first get/set of this field.
168      * @param field the field
169      * @param override true if caller has overridden accessibility
170      */
171     public FieldAccessor newFieldAccessor(Field field, boolean override) {
172         checkInitted();
173 
174         Field root = langReflectAccess.getRoot(field);
175         if (root != null) {
176             // FieldAccessor will use the root unless the modifiers have
177             // been overridden
178             if (root.getModifiers() == field.getModifiers() || !override) {
179                 field = root;
180             }
181         }
182         boolean isFinal = Modifier.isFinal(field.getModifiers());
183         boolean isReadOnly = isFinal && (!override || langReflectAccess.isTrustedFinalField(field));
184         return UnsafeFieldAccessorFactory.newFieldAccessor(field, isReadOnly);




185     }
186 
187     public MethodAccessor newMethodAccessor(Method method) {
188         checkInitted();
189 
190         if (Reflection.isCallerSensitive(method)) {
191             Method altMethod = findMethodForReflection(method);
192             if (altMethod != null) {
193                 method = altMethod;
194             }
195         }
196 
197         // use the root Method that will not cache caller class
198         Method root = langReflectAccess.getRoot(method);
199         if (root != null) {
200             method = root;
201         }
202 
203         if (noInflation && !method.getDeclaringClass().isHidden()) {
204             return new MethodAccessorGenerator().
205                 generateMethod(method.getDeclaringClass(),
206                                method.getName(),
207                                method.getParameterTypes(),
208                                method.getReturnType(),
209                                method.getExceptionTypes(),
210                                method.getModifiers());
211         } else {
212             NativeMethodAccessorImpl acc = new NativeMethodAccessorImpl(method);
213             return acc.getParent();




214         }
215     }
216 














217     public ConstructorAccessor newConstructorAccessor(Constructor<?> c) {
218         checkInitted();
219 
220         Class<?> declaringClass = c.getDeclaringClass();
221         if (Modifier.isAbstract(declaringClass.getModifiers())) {
222             return new InstantiationExceptionConstructorAccessorImpl(null);
223         }
224         if (declaringClass == Class.class) {
225             return new InstantiationExceptionConstructorAccessorImpl
226                 ("Can not instantiate java.lang.Class");
227         }
228 
229         // use the root Constructor that will not cache caller class
230         Constructor<?> root = langReflectAccess.getRoot(c);
231         if (root != null) {
232             c = root;
233         }
234 
235         // Bootstrapping issue: since we use Class.newInstance() in
236         // the ConstructorAccessor generation process, we have to
237         // break the cycle here.
238         if (Reflection.isSubclassOf(declaringClass,
239                                     ConstructorAccessorImpl.class)) {
240             return new BootstrapConstructorAccessorImpl(c);
241         }
242 
243         if (noInflation && !c.getDeclaringClass().isHidden()) {
244             return new MethodAccessorGenerator().
245                 generateConstructor(c.getDeclaringClass(),
246                                     c.getParameterTypes(),
247                                     c.getExceptionTypes(),
248                                     c.getModifiers());
249         } else {
250             NativeConstructorAccessorImpl acc = new NativeConstructorAccessorImpl(c);
251             return acc.getParent();















252         }
253     }
254 
255     //--------------------------------------------------------------------------
256     //
257     // Routines used by java.lang
258     //
259     //
260 
261     /** Creates a new java.lang.reflect.Constructor. Access checks as
262         per java.lang.reflect.AccessibleObject are not overridden. */
263     public Constructor<?> newConstructor(Class<?> declaringClass,
264                                          Class<?>[] parameterTypes,
265                                          Class<?>[] checkedExceptions,
266                                          int modifiers,
267                                          int slot,
268                                          String signature,
269                                          byte[] annotations,
270                                          byte[] parameterAnnotations)
271     {

606     public final Constructor<OptionalDataException> newOptionalDataExceptionForSerialization() {
607         try {
608             Constructor<OptionalDataException> boolCtor =
609                     OptionalDataException.class.getDeclaredConstructor(Boolean.TYPE);
610             boolCtor.setAccessible(true);
611             return boolCtor;
612         } catch (NoSuchMethodException ex) {
613             throw new InternalError("Constructor not found", ex);
614         }
615     }
616 
617     //--------------------------------------------------------------------------
618     //
619     // Internals only below this point
620     //
621 
622     static int inflationThreshold() {
623         return inflationThreshold;
624     }
625 
















626     /** We have to defer full initialization of this class until after
627         the static initializer is run since java.lang.reflect.Method's
628         static initializer (more properly, that for
629         java.lang.reflect.AccessibleObject) causes this class's to be
630         run, before the system properties are set up. */
631     private static void checkInitted() {
632         if (initted) return;
633 
634         // Defer initialization until module system is initialized so as
635         // to avoid inflation and spinning bytecode in unnamed modules
636         // during early startup.
637         if (!VM.isModuleSystemInited()) {
638             return;
639         }
640 
641         Properties props = GetPropertyAction.privilegedGetProperties();
642         String val = props.getProperty("sun.reflect.noInflation");
643         if (val != null && val.equals("true")) {
644             noInflation = true;
645         }
646 
647         val = props.getProperty("sun.reflect.inflationThreshold");
648         if (val != null) {
649             try {
650                 inflationThreshold = Integer.parseInt(val);
651             } catch (NumberFormatException e) {
652                 throw new RuntimeException("Unable to parse property sun.reflect.inflationThreshold", e);
653             }
654         }














655 
656         disableSerialConstructorChecks =
657             "true".equals(props.getProperty("jdk.disableSerialConstructorChecks"));
658 
659         initted = true;
660     }
661 
662     /**
663      * Returns true if classes are defined in the classloader and same package, false
664      * otherwise.
665      * @param cl1 a class
666      * @param cl2 another class
667      * @returns true if the two classes are in the same classloader and package
668      */
669     private static boolean packageEquals(Class<?> cl1, Class<?> cl2) {
670         assert !cl1.isArray() && !cl2.isArray();
671 
672         if (cl1 == cl2) {
673             return true;
674         }

 68     /* Method for static class initializer <clinit>, or null */
 69     private static volatile Method hasStaticInitializerMethod;
 70 
 71     //
 72     // "Inflation" mechanism. Loading bytecodes to implement
 73     // Method.invoke() and Constructor.newInstance() currently costs
 74     // 3-4x more than an invocation via native code for the first
 75     // invocation (though subsequent invocations have been benchmarked
 76     // to be over 20x faster). Unfortunately this cost increases
 77     // startup time for certain applications that use reflection
 78     // intensively (but only once per class) to bootstrap themselves.
 79     // To avoid this penalty we reuse the existing JVM entry points
 80     // for the first few invocations of Methods and Constructors and
 81     // then switch to the bytecode-based implementations.
 82     //
 83     // Package-private to be accessible to NativeMethodAccessorImpl
 84     // and NativeConstructorAccessorImpl
 85     private static boolean noInflation        = false;
 86     private static int     inflationThreshold = 15;
 87 
 88     //
 89     // New implementation uses direct invocation of method handles
 90     private static final int METHOD_MH_ACCESSOR      = 0x1;
 91     private static final int FIELD_MH_ACCESSOR       = 0x2;
 92     private static final int ALL_MH_ACCESSORS        = METHOD_MH_ACCESSOR|FIELD_MH_ACCESSOR;
 93 
 94     private static int     useDirectMethodHandle = ALL_MH_ACCESSORS;
 95     private static boolean useNativeAccessorOnly = false;  // for testing only
 96 
 97     // true if deserialization constructor checking is disabled
 98     private static boolean disableSerialConstructorChecks = false;
 99 
100     private final JavaLangReflectAccess langReflectAccess;
101     private ReflectionFactory() {
102         this.langReflectAccess = SharedSecrets.getJavaLangReflectAccess();
103     }
104 
105     /**
106      * A convenience class for acquiring the capability to instantiate
107      * reflective objects.  Use this instead of a raw call to {@link
108      * #getReflectionFactory} in order to avoid being limited by the
109      * permissions of your callers.
110      *
111      * <p>An instance of this class can be used as the argument of
112      * <code>AccessController.doPrivileged</code>.
113      */
114     public static final class GetReflectionFactoryAction
115         implements PrivilegedAction<ReflectionFactory> {
116         public ReflectionFactory run() {

129      * security exception.
130      *
131      * <p> The returned <code>ReflectionFactory</code> object should be
132      * carefully guarded by the caller, since it can be used to read and
133      * write private data and invoke private methods, as well as to load
134      * unverified bytecodes.  It must never be passed to untrusted code.
135      *
136      * @exception SecurityException if a security manager exists and its
137      *             <code>checkPermission</code> method doesn't allow
138      *             access to the RuntimePermission "reflectionFactoryAccess".  */
139     public static ReflectionFactory getReflectionFactory() {
140         @SuppressWarnings("removal")
141         SecurityManager security = System.getSecurityManager();
142         if (security != null) {
143             security.checkPermission(
144                 SecurityConstants.REFLECTION_FACTORY_ACCESS_PERMISSION);
145         }
146         return soleInstance;
147     }
148 


















149     //--------------------------------------------------------------------------
150     //
151     // Routines used by java.lang.reflect
152     //
153     //
154 
155     /*
156      * Note: this routine can cause the declaring class for the field
157      * be initialized and therefore must not be called until the
158      * first get/set of this field.
159      * @param field the field
160      * @param override true if caller has overridden accessibility
161      */
162     public FieldAccessor newFieldAccessor(Field field, boolean override) {
163         checkInitted();
164 
165         Field root = langReflectAccess.getRoot(field);
166         if (root != null) {
167             // FieldAccessor will use the root unless the modifiers have
168             // been overridden
169             if (root.getModifiers() == field.getModifiers() || !override) {
170                 field = root;
171             }
172         }
173         boolean isFinal = Modifier.isFinal(field.getModifiers());
174         boolean isReadOnly = isFinal && (!override || langReflectAccess.isTrustedFinalField(field));
175         if (useFieldHandleAccessor()) {
176             return MethodHandleAccessorFactory.newFieldAccessor(field, isReadOnly);
177         } else {
178             return UnsafeFieldAccessorFactory.newFieldAccessor(field, isReadOnly);
179         }
180     }
181 
182     public MethodAccessor newMethodAccessor(Method method, boolean callerSensitive) {
183         checkInitted();
184 







185         // use the root Method that will not cache caller class
186         Method root = langReflectAccess.getRoot(method);
187         if (root != null) {
188             method = root;
189         }
190 
191         if (useMethodHandleAccessor()) {
192             return MethodHandleAccessorFactory.newMethodAccessor(method, callerSensitive);






193         } else {
194             if (noInflation && !method.getDeclaringClass().isHidden()) {
195                 return generateMethodAccessor(method);
196             } else {
197                 NativeMethodAccessorImpl acc = new NativeMethodAccessorImpl(method);
198                 return acc.getParent();
199             }
200         }
201     }
202 
203     /**
204      * Generate the MethodAccessor that invokes the given method with
205      * bytecode invocation.
206      */
207     static MethodAccessorImpl generateMethodAccessor(Method method) {
208         return (MethodAccessorImpl)new MethodAccessorGenerator()
209                 .generateMethod(method.getDeclaringClass(),
210                                 method.getName(),
211                                 method.getParameterTypes(),
212                                 method.getReturnType(),
213                                 method.getExceptionTypes(),
214                                 method.getModifiers());
215     }
216 
217     public ConstructorAccessor newConstructorAccessor(Constructor<?> c) {
218         checkInitted();
219 
220         Class<?> declaringClass = c.getDeclaringClass();
221         if (Modifier.isAbstract(declaringClass.getModifiers())) {
222             return new InstantiationExceptionConstructorAccessorImpl(null);
223         }
224         if (declaringClass == Class.class) {
225             return new InstantiationExceptionConstructorAccessorImpl
226                 ("Can not instantiate java.lang.Class");
227         }
228 
229         // use the root Constructor that will not cache caller class
230         Constructor<?> root = langReflectAccess.getRoot(c);
231         if (root != null) {
232             c = root;
233         }
234 
235         if (useMethodHandleAccessor()) {
236             return MethodHandleAccessorFactory.newConstructorAccessor(c);












237         } else {
238             // Bootstrapping issue: since we use Class.newInstance() in
239             // the ConstructorAccessor generation process, we have to
240             // break the cycle here.
241             if (Reflection.isSubclassOf(declaringClass, ConstructorAccessorImpl.class)) {
242                 return new BootstrapConstructorAccessorImpl(c);
243             }
244 
245             if (noInflation && !c.getDeclaringClass().isHidden()) {
246                 return new MethodAccessorGenerator().
247                         generateConstructor(c.getDeclaringClass(),
248                                             c.getParameterTypes(),
249                                             c.getExceptionTypes(),
250                                             c.getModifiers());
251             } else {
252                 NativeConstructorAccessorImpl acc = new NativeConstructorAccessorImpl(c);
253                 return acc.getParent();
254             }
255         }
256     }
257 
258     //--------------------------------------------------------------------------
259     //
260     // Routines used by java.lang
261     //
262     //
263 
264     /** Creates a new java.lang.reflect.Constructor. Access checks as
265         per java.lang.reflect.AccessibleObject are not overridden. */
266     public Constructor<?> newConstructor(Class<?> declaringClass,
267                                          Class<?>[] parameterTypes,
268                                          Class<?>[] checkedExceptions,
269                                          int modifiers,
270                                          int slot,
271                                          String signature,
272                                          byte[] annotations,
273                                          byte[] parameterAnnotations)
274     {

609     public final Constructor<OptionalDataException> newOptionalDataExceptionForSerialization() {
610         try {
611             Constructor<OptionalDataException> boolCtor =
612                     OptionalDataException.class.getDeclaredConstructor(Boolean.TYPE);
613             boolCtor.setAccessible(true);
614             return boolCtor;
615         } catch (NoSuchMethodException ex) {
616             throw new InternalError("Constructor not found", ex);
617         }
618     }
619 
620     //--------------------------------------------------------------------------
621     //
622     // Internals only below this point
623     //
624 
625     static int inflationThreshold() {
626         return inflationThreshold;
627     }
628 
629     static boolean noInflation() {
630         return noInflation;
631     }
632 
633     static boolean useMethodHandleAccessor() {
634         return (useDirectMethodHandle & METHOD_MH_ACCESSOR) == METHOD_MH_ACCESSOR;
635     }
636 
637     static boolean useFieldHandleAccessor() {
638         return (useDirectMethodHandle & FIELD_MH_ACCESSOR) == FIELD_MH_ACCESSOR;
639     }
640 
641     static boolean useNativeAccessorOnly() {
642         return useNativeAccessorOnly;
643     }
644 
645     /** We have to defer full initialization of this class until after
646         the static initializer is run since java.lang.reflect.Method's
647         static initializer (more properly, that for
648         java.lang.reflect.AccessibleObject) causes this class's to be
649         run, before the system properties are set up. */
650     private static void checkInitted() {
651         if (initted) return;
652 
653         // Defer initialization until module system is initialized so as
654         // to avoid inflation and spinning bytecode in unnamed modules
655         // during early startup.
656         if (!VM.isModuleSystemInited()) {
657             return;
658         }
659 
660         Properties props = GetPropertyAction.privilegedGetProperties();
661         String val = props.getProperty("sun.reflect.noInflation");
662         if (val != null && val.equals("true")) {
663             noInflation = true;
664         }
665 
666         val = props.getProperty("sun.reflect.inflationThreshold");
667         if (val != null) {
668             try {
669                 inflationThreshold = Integer.parseInt(val);
670             } catch (NumberFormatException e) {
671                 throw new RuntimeException("Unable to parse property sun.reflect.inflationThreshold", e);
672             }
673         }
674         val = props.getProperty("jdk.reflect.useDirectMethodHandle");
675         if (val != null) {
676             if (val.equals("false")) {
677                 useDirectMethodHandle = 0;
678             } else if (val.equals("methods")) {
679                 useDirectMethodHandle = METHOD_MH_ACCESSOR;
680             } else if (val.equals("fields")) {
681                 useDirectMethodHandle = FIELD_MH_ACCESSOR;
682             }
683         }
684         val = props.getProperty("jdk.reflect.useNativeAccessorOnly");
685         if (val != null && val.equals("true")) {
686             useNativeAccessorOnly = true;
687         }
688 
689         disableSerialConstructorChecks =
690             "true".equals(props.getProperty("jdk.disableSerialConstructorChecks"));
691 
692         initted = true;
693     }
694 
695     /**
696      * Returns true if classes are defined in the classloader and same package, false
697      * otherwise.
698      * @param cl1 a class
699      * @param cl2 another class
700      * @returns true if the two classes are in the same classloader and package
701      */
702     private static boolean packageEquals(Class<?> cl1, Class<?> cl2) {
703         assert !cl1.isArray() && !cl2.isArray();
704 
705         if (cl1 == cl2) {
706             return true;
707         }
< prev index next >