001: /*
002: * Copyright 2001-2004 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package sun.reflect;
027:
028: import java.lang.reflect.Field;
029: import java.lang.reflect.Method;
030: import java.lang.reflect.Constructor;
031: import java.lang.reflect.Modifier;
032: import java.security.AccessController;
033: import java.security.Permission;
034: import java.security.PrivilegedAction;
035:
036: /** <P> The master factory for all reflective objects, both those in
037: java.lang.reflect (Fields, Methods, Constructors) as well as their
038: delegates (FieldAccessors, MethodAccessors, ConstructorAccessors).
039: </P>
040:
041: <P> The methods in this class are extremely unsafe and can cause
042: subversion of both the language and the verifier. For this reason,
043: they are all instance methods, and access to the constructor of
044: this factory is guarded by a security check, in similar style to
045: {@link sun.misc.Unsafe}. </P>
046: */
047:
048: public class ReflectionFactory {
049:
050: private static boolean initted = false;
051: private static Permission reflectionFactoryAccessPerm = new RuntimePermission(
052: "reflectionFactoryAccess");
053: private static ReflectionFactory soleInstance = new ReflectionFactory();
054: // Provides access to package-private mechanisms in java.lang.reflect
055: private static volatile LangReflectAccess langReflectAccess;
056:
057: //
058: // "Inflation" mechanism. Loading bytecodes to implement
059: // Method.invoke() and Constructor.newInstance() currently costs
060: // 3-4x more than an invocation via native code for the first
061: // invocation (though subsequent invocations have been benchmarked
062: // to be over 20x faster). Unfortunately this cost increases
063: // startup time for certain applications that use reflection
064: // intensively (but only once per class) to bootstrap themselves.
065: // To avoid this penalty we reuse the existing JVM entry points
066: // for the first few invocations of Methods and Constructors and
067: // then switch to the bytecode-based implementations.
068: //
069: // Package-private to be accessible to NativeMethodAccessorImpl
070: // and NativeConstructorAccessorImpl
071: private static boolean noInflation = false;
072: private static int inflationThreshold = 15;
073:
074: private ReflectionFactory() {
075: }
076:
077: /**
078: * A convenience class for acquiring the capability to instantiate
079: * reflective objects. Use this instead of a raw call to {@link
080: * #getReflectionFactory} in order to avoid being limited by the
081: * permissions of your callers.
082: *
083: * <p>An instance of this class can be used as the argument of
084: * <code>AccessController.doPrivileged</code>.
085: */
086: public static final class GetReflectionFactoryAction implements
087: PrivilegedAction {
088: public Object run() {
089: return getReflectionFactory();
090: }
091: }
092:
093: /**
094: * Provides the caller with the capability to instantiate reflective
095: * objects.
096: *
097: * <p> First, if there is a security manager, its
098: * <code>checkPermission</code> method is called with a {@link
099: * 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,
141: override);
142: }
143:
144: public MethodAccessor newMethodAccessor(Method method) {
145: checkInitted();
146:
147: if (noInflation) {
148: return new MethodAccessorGenerator().generateMethod(method
149: .getDeclaringClass(), method.getName(), method
150: .getParameterTypes(), method.getReturnType(),
151: method.getExceptionTypes(), method.getModifiers());
152: } else {
153: NativeMethodAccessorImpl acc = new NativeMethodAccessorImpl(
154: method);
155: DelegatingMethodAccessorImpl res = new DelegatingMethodAccessorImpl(
156: acc);
157: acc.setParent(res);
158: return res;
159: }
160: }
161:
162: public ConstructorAccessor newConstructorAccessor(Constructor c) {
163: checkInitted();
164:
165: Class declaringClass = c.getDeclaringClass();
166: if (Modifier.isAbstract(declaringClass.getModifiers())) {
167: return new InstantiationExceptionConstructorAccessorImpl(
168: null);
169: }
170: if (declaringClass == Class.class) {
171: return new InstantiationExceptionConstructorAccessorImpl(
172: "Can not instantiate java.lang.Class");
173: }
174: // Bootstrapping issue: since we use Class.newInstance() in
175: // the ConstructorAccessor generation process, we have to
176: // break the cycle here.
177: if (Reflection.isSubclassOf(declaringClass,
178: ConstructorAccessorImpl.class)) {
179: return new BootstrapConstructorAccessorImpl(c);
180: }
181:
182: if (noInflation) {
183: return new MethodAccessorGenerator().generateConstructor(c
184: .getDeclaringClass(), c.getParameterTypes(), c
185: .getExceptionTypes(), c.getModifiers());
186: } else {
187: NativeConstructorAccessorImpl acc = new NativeConstructorAccessorImpl(
188: c);
189: DelegatingConstructorAccessorImpl res = new DelegatingConstructorAccessorImpl(
190: acc);
191: acc.setParent(res);
192: return res;
193: }
194: }
195:
196: //--------------------------------------------------------------------------
197: //
198: // Routines used by java.lang
199: //
200: //
201:
202: /** Creates a new java.lang.reflect.Field. Access checks as per
203: java.lang.reflect.AccessibleObject are not overridden. */
204: public Field newField(Class declaringClass, String name,
205: Class type, int modifiers, int slot, String signature,
206: byte[] annotations) {
207: return langReflectAccess().newField(declaringClass, name, type,
208: modifiers, slot, signature, annotations);
209: }
210:
211: /** Creates a new java.lang.reflect.Method. Access checks as per
212: java.lang.reflect.AccessibleObject are not overridden. */
213: public Method newMethod(Class declaringClass, String name,
214: Class[] parameterTypes, Class returnType,
215: Class[] checkedExceptions, int modifiers, int slot,
216: String signature, byte[] annotations,
217: byte[] parameterAnnotations, byte[] annotationDefault) {
218: return langReflectAccess().newMethod(declaringClass, name,
219: parameterTypes, returnType, checkedExceptions,
220: modifiers, slot, signature, annotations,
221: parameterAnnotations, annotationDefault);
222: }
223:
224: /** Creates a new java.lang.reflect.Constructor. Access checks as
225: per java.lang.reflect.AccessibleObject are not overridden. */
226: public Constructor newConstructor(Class declaringClass,
227: Class[] parameterTypes, Class[] checkedExceptions,
228: int modifiers, int slot, String signature,
229: byte[] annotations, byte[] parameterAnnotations) {
230: return langReflectAccess().newConstructor(declaringClass,
231: parameterTypes, checkedExceptions, modifiers, slot,
232: signature, annotations, parameterAnnotations);
233: }
234:
235: /** Gets the MethodAccessor object for a java.lang.reflect.Method */
236: public MethodAccessor getMethodAccessor(Method m) {
237: return langReflectAccess().getMethodAccessor(m);
238: }
239:
240: /** Sets the MethodAccessor object for a java.lang.reflect.Method */
241: public void setMethodAccessor(Method m, MethodAccessor accessor) {
242: langReflectAccess().setMethodAccessor(m, accessor);
243: }
244:
245: /** Gets the ConstructorAccessor object for a
246: java.lang.reflect.Constructor */
247: public ConstructorAccessor getConstructorAccessor(Constructor c) {
248: return langReflectAccess().getConstructorAccessor(c);
249: }
250:
251: /** Sets the ConstructorAccessor object for a
252: java.lang.reflect.Constructor */
253: public void setConstructorAccessor(Constructor c,
254: ConstructorAccessor accessor) {
255: langReflectAccess().setConstructorAccessor(c, accessor);
256: }
257:
258: /** Makes a copy of the passed method. The returned method is a
259: "child" of the passed one; see the comments in Method.java for
260: details. */
261: public Method copyMethod(Method arg) {
262: return langReflectAccess().copyMethod(arg);
263: }
264:
265: /** Makes a copy of the passed field. The returned field is a
266: "child" of the passed one; see the comments in Field.java for
267: details. */
268: public Field copyField(Field arg) {
269: return langReflectAccess().copyField(arg);
270: }
271:
272: /** Makes a copy of the passed constructor. The returned
273: constructor is a "child" of the passed one; see the comments
274: in Constructor.java for details. */
275: public Constructor copyConstructor(Constructor arg) {
276: return langReflectAccess().copyConstructor(arg);
277: }
278:
279: //--------------------------------------------------------------------------
280: //
281: // Routines used by serialization
282: //
283: //
284:
285: public Constructor newConstructorForSerialization(
286: Class classToInstantiate, Constructor constructorToCall) {
287: // Fast path
288: if (constructorToCall.getDeclaringClass() == classToInstantiate) {
289: return constructorToCall;
290: }
291:
292: ConstructorAccessor acc = new MethodAccessorGenerator()
293: .generateSerializationConstructor(classToInstantiate,
294: constructorToCall.getParameterTypes(),
295: constructorToCall.getExceptionTypes(),
296: constructorToCall.getModifiers(),
297: constructorToCall.getDeclaringClass());
298: Constructor c = newConstructor(constructorToCall
299: .getDeclaringClass(), constructorToCall
300: .getParameterTypes(), constructorToCall
301: .getExceptionTypes(), constructorToCall.getModifiers(),
302: langReflectAccess().getConstructorSlot(
303: constructorToCall), langReflectAccess()
304: .getConstructorSignature(constructorToCall),
305: langReflectAccess().getConstructorAnnotations(
306: constructorToCall), langReflectAccess()
307: .getConstructorParameterAnnotations(
308: constructorToCall));
309: setConstructorAccessor(c, acc);
310: return c;
311: }
312:
313: //--------------------------------------------------------------------------
314: //
315: // Internals only below this point
316: //
317:
318: static int inflationThreshold() {
319: return inflationThreshold;
320: }
321:
322: /** We have to defer full initialization of this class until after
323: the static initializer is run since java.lang.reflect.Method's
324: static initializer (more properly, that for
325: java.lang.reflect.AccessibleObject) causes this class's to be
326: run, before the system properties are set up. */
327: private static void checkInitted() {
328: if (initted)
329: return;
330: AccessController.doPrivileged(new PrivilegedAction() {
331: public Object run() {
332: // Tests to ensure the system properties table is fully
333: // initialized. This is needed because reflection code is
334: // called very early in the initialization process (before
335: // command-line arguments have been parsed and therefore
336: // these user-settable properties installed.) We assume that
337: // if System.out is non-null then the System class has been
338: // fully initialized and that the bulk of the startup code
339: // has been run.
340:
341: if (System.out == null) {
342: // java.lang.System not yet fully initialized
343: return null;
344: }
345:
346: String val = System
347: .getProperty("sun.reflect.noInflation");
348: if (val != null && val.equals("true")) {
349: noInflation = true;
350: }
351:
352: val = System
353: .getProperty("sun.reflect.inflationThreshold");
354: if (val != null) {
355: try {
356: inflationThreshold = Integer.parseInt(val);
357: } catch (NumberFormatException e) {
358: throw (RuntimeException) new RuntimeException(
359: "Unable to parse property sun.reflect.inflationThreshold")
360: .initCause(e);
361: }
362: }
363:
364: initted = true;
365: return null;
366: }
367: });
368: }
369:
370: private static LangReflectAccess langReflectAccess() {
371: if (langReflectAccess == null) {
372: // Call a static method to get class java.lang.reflect.Modifier
373: // initialized. Its static initializer will cause
374: // setLangReflectAccess() to be called from the context of the
375: // java.lang.reflect package.
376: Modifier.isPublic(Modifier.PUBLIC);
377: }
378: return langReflectAccess;
379: }
380: }
|