1 /*
2 * Copyright (c) 2001, 2008, 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.lang.reflect.Field;
29 import java.lang.reflect.Method;
30 import java.lang.reflect.Constructor;
31 import java.lang.reflect.Modifier;
32 import java.security.AccessController;
33 import java.security.Permission;
34 import java.security.PrivilegedAction;
35
36 /** <P> The master factory for all reflective objects, both those in
37 java.lang.reflect (Fields, Methods, Constructors) as well as their
38 delegates (FieldAccessors, MethodAccessors, ConstructorAccessors).
39 </P>
40
41 <P> The methods in this class are extremely unsafe and can cause
42 subversion of both the language and the verifier. For this reason,
43 they are all instance methods, and access to the constructor of
44 this factory is guarded by a security check, in similar style to
45 {@link sun.misc.Unsafe}. </P>
46 */
47
48 public class ReflectionFactory {
49
50 private static boolean initted = false;
51 private static Permission reflectionFactoryAccessPerm
52 = new RuntimePermission("reflectionFactoryAccess");
53 private static ReflectionFactory soleInstance = new ReflectionFactory();
54 // Provides access to package-private mechanisms in java.lang.reflect
55 private static volatile LangReflectAccess langReflectAccess;
56
57 //
58 // "Inflation" mechanism. Loading bytecodes to implement
59 // Method.invoke() and Constructor.newInstance() currently costs
60 // 3-4x more than an invocation via native code for the first
61 // invocation (though subsequent invocations have been benchmarked
62 // to be over 20x faster). Unfortunately this cost increases
63 // startup time for certain applications that use reflection
64 // intensively (but only once per class) to bootstrap themselves.
65 // To avoid this penalty we reuse the existing JVM entry points
66 // for the first few invocations of Methods and Constructors and
67 // then switch to the bytecode-based implementations.
68 //
69 // Package-private to be accessible to NativeMethodAccessorImpl
70 // and NativeConstructorAccessorImpl
71 private static boolean noInflation = false;
72 private static int inflationThreshold = 15;
73
74 private ReflectionFactory() {
75 }
76
77 /**
78 * A convenience class for acquiring the capability to instantiate
79 * reflective objects. Use this instead of a raw call to {@link
80 * #getReflectionFactory} in order to avoid being limited by the
81 * permissions of your callers.
82 *
83 * <p>An instance of this class can be used as the argument of
84 * <code>AccessController.doPrivileged</code>.
85 */
86 public static final class GetReflectionFactoryAction
87 implements PrivilegedAction<ReflectionFactory> {
88 public ReflectionFactory run() {
89 return getReflectionFactory();
90 }
91 }
92
93 /**
94 * Provides the caller with the capability to instantiate reflective
95 * objects.
96 *
97 * <p> First, if there is a security manager, its
98 * <code>checkPermission</code> method is called with a {@link
99 * java.lang.RuntimePermission} with target
100 * <code>"reflectionFactoryAccess"</code>. This may result in a
101 * security exception.
102 *
103 * <p> The returned <code>ReflectionFactory</code> object should be
104 * carefully guarded by the caller, since it can be used to read and
105 * write private data and invoke private methods, as well as to load
106 * unverified bytecodes. It must never be passed to untrusted code.
107 *
108 * @exception SecurityException if a security manager exists and its
109 * <code>checkPermission</code> method doesn't allow
110 * access to the RuntimePermission "reflectionFactoryAccess". */
111 public static ReflectionFactory getReflectionFactory() {
112 SecurityManager security = System.getSecurityManager();
113 if (security != null) {
114 // TO DO: security.checkReflectionFactoryAccess();
115 security.checkPermission(reflectionFactoryAccessPerm);
116 }
117 return soleInstance;
118 }
119
120 //--------------------------------------------------------------------------
121 //
122 // Routines used by java.lang.reflect
123 //
124 //
125
126 /** Called only by java.lang.reflect.Modifier's static initializer */
127 public void setLangReflectAccess(LangReflectAccess access) {
128 langReflectAccess = access;
129 }
130
131 /**
132 * Note: this routine can cause the declaring class for the field
133 * be initialized and therefore must not be called until the
134 * first get/set of this field.
135 * @param field the field
136 * @param override true if caller has overridden aaccessibility
137 */
138 public FieldAccessor newFieldAccessor(Field field, boolean override) {
139 checkInitted();
140 return UnsafeFieldAccessorFactory.newFieldAccessor(field, override);
141 }
142
143 public MethodAccessor newMethodAccessor(Method method) {
144 checkInitted();
145
146 if (noInflation) {
147 return new MethodAccessorGenerator().
148 generateMethod(method.getDeclaringClass(),
149 method.getName(),
150 method.getParameterTypes(),
151 method.getReturnType(),
152 method.getExceptionTypes(),
153 method.getModifiers());
154 } else {
155 NativeMethodAccessorImpl acc =
156 new NativeMethodAccessorImpl(method);
157 DelegatingMethodAccessorImpl res =
158 new DelegatingMethodAccessorImpl(acc);
159 acc.setParent(res);
160 return res;
161 }
162 }
163
164 public ConstructorAccessor newConstructorAccessor(Constructor c) {
165 checkInitted();
166
167 Class<?> declaringClass = c.getDeclaringClass();
168 if (Modifier.isAbstract(declaringClass.getModifiers())) {
169 return new InstantiationExceptionConstructorAccessorImpl(null);
170 }
171 if (declaringClass == Class.class) {
172 return new InstantiationExceptionConstructorAccessorImpl
173 ("Can not instantiate java.lang.Class");
174 }
175 // Bootstrapping issue: since we use Class.newInstance() in
176 // the ConstructorAccessor generation process, we have to
177 // break the cycle here.
178 if (Reflection.isSubclassOf(declaringClass,
179 ConstructorAccessorImpl.class)) {
180 return new BootstrapConstructorAccessorImpl(c);
181 }
182
183 if (noInflation) {
184 return new MethodAccessorGenerator().
185 generateConstructor(c.getDeclaringClass(),
186 c.getParameterTypes(),
187 c.getExceptionTypes(),
188 c.getModifiers());
189 } else {
190 NativeConstructorAccessorImpl acc =
191 new NativeConstructorAccessorImpl(c);
192 DelegatingConstructorAccessorImpl res =
193 new DelegatingConstructorAccessorImpl(acc);
194 acc.setParent(res);
195 return res;
196 }
197 }
198
199 //--------------------------------------------------------------------------
200 //
201 // Routines used by java.lang
202 //
203 //
204
205 /** Creates a new java.lang.reflect.Field. Access checks as per
206 java.lang.reflect.AccessibleObject are not overridden. */
207 public Field newField(Class<?> declaringClass,
208 String name,
209 Class<?> type,
210 int modifiers,
211 int slot,
212 String signature,
213 byte[] annotations)
214 {
215 return langReflectAccess().newField(declaringClass,
216 name,
217 type,
218 modifiers,
219 slot,
220 signature,
221 annotations);
222 }
223
224 /** Creates a new java.lang.reflect.Method. Access checks as per
225 java.lang.reflect.AccessibleObject are not overridden. */
226 public Method newMethod(Class<?> declaringClass,
227 String name,
228 Class<?>[] parameterTypes,
229 Class<?> returnType,
230 Class<?>[] checkedExceptions,
231 int modifiers,
232 int slot,
233 String signature,
234 byte[] annotations,
235 byte[] parameterAnnotations,
236 byte[] annotationDefault)
237 {
238 return langReflectAccess().newMethod(declaringClass,
239 name,
240 parameterTypes,
241 returnType,
242 checkedExceptions,
243 modifiers,
244 slot,
245 signature,
246 annotations,
247 parameterAnnotations,
248 annotationDefault);
249 }
250
251 /** Creates a new java.lang.reflect.Constructor. Access checks as
252 per java.lang.reflect.AccessibleObject are not overridden. */
253 public Constructor newConstructor(Class<?> declaringClass,
254 Class<?>[] parameterTypes,
255 Class<?>[] checkedExceptions,
256 int modifiers,
257 int slot,
258 String signature,
259 byte[] annotations,
260 byte[] parameterAnnotations)
261 {
262 return langReflectAccess().newConstructor(declaringClass,
263 parameterTypes,
264 checkedExceptions,
265 modifiers,
266 slot,
267 signature,
268 annotations,
269 parameterAnnotations);
270 }
271
272 /** Gets the MethodAccessor object for a java.lang.reflect.Method */
273 public MethodAccessor getMethodAccessor(Method m) {
274 return langReflectAccess().getMethodAccessor(m);
275 }
276
277 /** Sets the MethodAccessor object for a java.lang.reflect.Method */
278 public void setMethodAccessor(Method m, MethodAccessor accessor) {
279 langReflectAccess().setMethodAccessor(m, accessor);
280 }
281
282 /** Gets the ConstructorAccessor object for a
283 java.lang.reflect.Constructor */
284 public ConstructorAccessor getConstructorAccessor(Constructor c) {
285 return langReflectAccess().getConstructorAccessor(c);
286 }
287
288 /** Sets the ConstructorAccessor object for a
289 java.lang.reflect.Constructor */
290 public void setConstructorAccessor(Constructor c,
291 ConstructorAccessor accessor)
292 {
293 langReflectAccess().setConstructorAccessor(c, accessor);
294 }
295
296 /** Makes a copy of the passed method. The returned method is a
297 "child" of the passed one; see the comments in Method.java for
298 details. */
299 public Method copyMethod(Method arg) {
300 return langReflectAccess().copyMethod(arg);
301 }
302
303 /** Makes a copy of the passed field. The returned field is a
304 "child" of the passed one; see the comments in Field.java for
305 details. */
306 public Field copyField(Field arg) {
307 return langReflectAccess().copyField(arg);
308 }
309
310 /** Makes a copy of the passed constructor. The returned
311 constructor is a "child" of the passed one; see the comments
312 in Constructor.java for details. */
313 public <T> Constructor<T> copyConstructor(Constructor<T> arg) {
314 return langReflectAccess().copyConstructor(arg);
315 }
316
317 //--------------------------------------------------------------------------
318 //
319 // Routines used by serialization
320 //
321 //
322
323 public Constructor newConstructorForSerialization
324 (Class<?> classToInstantiate, Constructor constructorToCall)
325 {
326 // Fast path
327 if (constructorToCall.getDeclaringClass() == classToInstantiate) {
328 return constructorToCall;
329 }
330
331 ConstructorAccessor acc = new MethodAccessorGenerator().
332 generateSerializationConstructor(classToInstantiate,
333 constructorToCall.getParameterTypes(),
334 constructorToCall.getExceptionTypes(),
335 constructorToCall.getModifiers(),
336 constructorToCall.getDeclaringClass());
337 Constructor c = newConstructor(constructorToCall.getDeclaringClass(),
338 constructorToCall.getParameterTypes(),
339 constructorToCall.getExceptionTypes(),
340 constructorToCall.getModifiers(),
341 langReflectAccess().
342 getConstructorSlot(constructorToCall),
343 langReflectAccess().
344 getConstructorSignature(constructorToCall),
345 langReflectAccess().
346 getConstructorAnnotations(constructorToCall),
347 langReflectAccess().
348 getConstructorParameterAnnotations(constructorToCall));
349 setConstructorAccessor(c, acc);
350 return c;
351 }
352
353 //--------------------------------------------------------------------------
354 //
355 // Internals only below this point
356 //
357
358 static int inflationThreshold() {
359 return inflationThreshold;
360 }
361
362 /** We have to defer full initialization of this class until after
363 the static initializer is run since java.lang.reflect.Method's
364 static initializer (more properly, that for
365 java.lang.reflect.AccessibleObject) causes this class's to be
366 run, before the system properties are set up. */
367 private static void checkInitted() {
368 if (initted) return;
369 AccessController.doPrivileged(
370 new PrivilegedAction<Void>() {
371 public Void run() {
372 // Tests to ensure the system properties table is fully
373 // initialized. This is needed because reflection code is
374 // called very early in the initialization process (before
375 // command-line arguments have been parsed and therefore
376 // these user-settable properties installed.) We assume that
377 // if System.out is non-null then the System class has been
378 // fully initialized and that the bulk of the startup code
379 // has been run.
380
381 if (System.out == null) {
382 // java.lang.System not yet fully initialized
383 return null;
384 }
385
386 String val = System.getProperty("sun.reflect.noInflation");
387 if (val != null && val.equals("true")) {
388 noInflation = true;
389 }
390
391 val = System.getProperty("sun.reflect.inflationThreshold");
392 if (val != null) {
393 try {
394 inflationThreshold = Integer.parseInt(val);
395 } catch (NumberFormatException e) {
396 throw (RuntimeException)
397 new RuntimeException("Unable to parse property sun.reflect.inflationThreshold").
398 initCause(e);
399 }
400 }
401
402 initted = true;
403 return null;
404 }
405 });
406 }
407
408 private static LangReflectAccess langReflectAccess() {
409 if (langReflectAccess == null) {
410 // Call a static method to get class java.lang.reflect.Modifier
411 // initialized. Its static initializer will cause
412 // setLangReflectAccess() to be called from the context of the
413 // java.lang.reflect package.
414 Modifier.isPublic(Modifier.PUBLIC);
415 }
416 return langReflectAccess;
417 }
418 }