0N/A/*
2362N/A * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage sun.reflect;
0N/A
0N/Aimport java.lang.reflect.Field;
0N/Aimport java.lang.reflect.Method;
0N/Aimport java.lang.reflect.Constructor;
0N/Aimport java.lang.reflect.Modifier;
0N/Aimport java.security.AccessController;
0N/Aimport java.security.Permission;
0N/Aimport java.security.PrivilegedAction;
0N/A
0N/A/** <P> The master factory for all reflective objects, both those in
0N/A java.lang.reflect (Fields, Methods, Constructors) as well as their
0N/A delegates (FieldAccessors, MethodAccessors, ConstructorAccessors).
0N/A </P>
0N/A
0N/A <P> The methods in this class are extremely unsafe and can cause
0N/A subversion of both the language and the verifier. For this reason,
0N/A they are all instance methods, and access to the constructor of
0N/A this factory is guarded by a security check, in similar style to
0N/A {@link sun.misc.Unsafe}. </P>
0N/A*/
0N/A
0N/Apublic class ReflectionFactory {
0N/A
0N/A private static boolean initted = false;
0N/A private static Permission reflectionFactoryAccessPerm
0N/A = new RuntimePermission("reflectionFactoryAccess");
0N/A private static ReflectionFactory soleInstance = new ReflectionFactory();
0N/A // Provides access to package-private mechanisms in java.lang.reflect
0N/A private static volatile LangReflectAccess langReflectAccess;
0N/A
0N/A //
0N/A // "Inflation" mechanism. Loading bytecodes to implement
0N/A // Method.invoke() and Constructor.newInstance() currently costs
0N/A // 3-4x more than an invocation via native code for the first
0N/A // invocation (though subsequent invocations have been benchmarked
0N/A // to be over 20x faster). Unfortunately this cost increases
0N/A // startup time for certain applications that use reflection
0N/A // intensively (but only once per class) to bootstrap themselves.
0N/A // To avoid this penalty we reuse the existing JVM entry points
0N/A // for the first few invocations of Methods and Constructors and
0N/A // then switch to the bytecode-based implementations.
0N/A //
0N/A // Package-private to be accessible to NativeMethodAccessorImpl
0N/A // and NativeConstructorAccessorImpl
0N/A private static boolean noInflation = false;
0N/A private static int inflationThreshold = 15;
0N/A
0N/A private ReflectionFactory() {
0N/A }
0N/A
0N/A /**
0N/A * A convenience class for acquiring the capability to instantiate
0N/A * reflective objects. Use this instead of a raw call to {@link
0N/A * #getReflectionFactory} in order to avoid being limited by the
0N/A * permissions of your callers.
0N/A *
0N/A * <p>An instance of this class can be used as the argument of
0N/A * <code>AccessController.doPrivileged</code>.
0N/A */
0N/A public static final class GetReflectionFactoryAction
28N/A implements PrivilegedAction<ReflectionFactory> {
28N/A public ReflectionFactory run() {
0N/A return getReflectionFactory();
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * Provides the caller with the capability to instantiate reflective
0N/A * objects.
0N/A *
0N/A * <p> First, if there is a security manager, its
0N/A * <code>checkPermission</code> method is called with a {@link
0N/A * java.lang.RuntimePermission} with target
0N/A * <code>"reflectionFactoryAccess"</code>. This may result in a
0N/A * security exception.
0N/A *
0N/A * <p> The returned <code>ReflectionFactory</code> object should be
0N/A * carefully guarded by the caller, since it can be used to read and
0N/A * write private data and invoke private methods, as well as to load
0N/A * unverified bytecodes. It must never be passed to untrusted code.
0N/A *
0N/A * @exception SecurityException if a security manager exists and its
0N/A * <code>checkPermission</code> method doesn't allow
0N/A * access to the RuntimePermission "reflectionFactoryAccess". */
0N/A public static ReflectionFactory getReflectionFactory() {
0N/A SecurityManager security = System.getSecurityManager();
0N/A if (security != null) {
0N/A // TO DO: security.checkReflectionFactoryAccess();
0N/A security.checkPermission(reflectionFactoryAccessPerm);
0N/A }
0N/A return soleInstance;
0N/A }
0N/A
0N/A //--------------------------------------------------------------------------
0N/A //
0N/A // Routines used by java.lang.reflect
0N/A //
0N/A //
0N/A
0N/A /** Called only by java.lang.reflect.Modifier's static initializer */
0N/A public void setLangReflectAccess(LangReflectAccess access) {
0N/A langReflectAccess = access;
0N/A }
0N/A
0N/A /**
0N/A * Note: this routine can cause the declaring class for the field
0N/A * be initialized and therefore must not be called until the
0N/A * first get/set of this field.
0N/A * @param field the field
0N/A * @param override true if caller has overridden aaccessibility
0N/A */
0N/A public FieldAccessor newFieldAccessor(Field field, boolean override) {
0N/A checkInitted();
0N/A return UnsafeFieldAccessorFactory.newFieldAccessor(field, override);
0N/A }
0N/A
0N/A public MethodAccessor newMethodAccessor(Method method) {
0N/A checkInitted();
0N/A
0N/A if (noInflation) {
0N/A return new MethodAccessorGenerator().
0N/A generateMethod(method.getDeclaringClass(),
0N/A method.getName(),
0N/A method.getParameterTypes(),
0N/A method.getReturnType(),
0N/A method.getExceptionTypes(),
0N/A method.getModifiers());
0N/A } else {
0N/A NativeMethodAccessorImpl acc =
0N/A new NativeMethodAccessorImpl(method);
0N/A DelegatingMethodAccessorImpl res =
0N/A new DelegatingMethodAccessorImpl(acc);
0N/A acc.setParent(res);
0N/A return res;
0N/A }
0N/A }
0N/A
0N/A public ConstructorAccessor newConstructorAccessor(Constructor c) {
0N/A checkInitted();
0N/A
28N/A Class<?> declaringClass = c.getDeclaringClass();
0N/A if (Modifier.isAbstract(declaringClass.getModifiers())) {
0N/A return new InstantiationExceptionConstructorAccessorImpl(null);
0N/A }
0N/A if (declaringClass == Class.class) {
0N/A return new InstantiationExceptionConstructorAccessorImpl
0N/A ("Can not instantiate java.lang.Class");
0N/A }
0N/A // Bootstrapping issue: since we use Class.newInstance() in
0N/A // the ConstructorAccessor generation process, we have to
0N/A // break the cycle here.
0N/A if (Reflection.isSubclassOf(declaringClass,
0N/A ConstructorAccessorImpl.class)) {
0N/A return new BootstrapConstructorAccessorImpl(c);
0N/A }
0N/A
0N/A if (noInflation) {
0N/A return new MethodAccessorGenerator().
0N/A generateConstructor(c.getDeclaringClass(),
0N/A c.getParameterTypes(),
0N/A c.getExceptionTypes(),
0N/A c.getModifiers());
0N/A } else {
0N/A NativeConstructorAccessorImpl acc =
0N/A new NativeConstructorAccessorImpl(c);
0N/A DelegatingConstructorAccessorImpl res =
0N/A new DelegatingConstructorAccessorImpl(acc);
0N/A acc.setParent(res);
0N/A return res;
0N/A }
0N/A }
0N/A
0N/A //--------------------------------------------------------------------------
0N/A //
0N/A // Routines used by java.lang
0N/A //
0N/A //
0N/A
0N/A /** Creates a new java.lang.reflect.Field. Access checks as per
0N/A java.lang.reflect.AccessibleObject are not overridden. */
28N/A public Field newField(Class<?> declaringClass,
0N/A String name,
28N/A Class<?> type,
0N/A int modifiers,
0N/A int slot,
0N/A String signature,
0N/A byte[] annotations)
0N/A {
0N/A return langReflectAccess().newField(declaringClass,
0N/A name,
0N/A type,
0N/A modifiers,
0N/A slot,
0N/A signature,
0N/A annotations);
0N/A }
0N/A
0N/A /** Creates a new java.lang.reflect.Method. Access checks as per
0N/A java.lang.reflect.AccessibleObject are not overridden. */
28N/A public Method newMethod(Class<?> declaringClass,
0N/A String name,
28N/A Class<?>[] parameterTypes,
28N/A Class<?> returnType,
28N/A Class<?>[] checkedExceptions,
0N/A int modifiers,
0N/A int slot,
0N/A String signature,
0N/A byte[] annotations,
0N/A byte[] parameterAnnotations,
0N/A byte[] annotationDefault)
0N/A {
0N/A return langReflectAccess().newMethod(declaringClass,
0N/A name,
0N/A parameterTypes,
0N/A returnType,
0N/A checkedExceptions,
0N/A modifiers,
0N/A slot,
0N/A signature,
0N/A annotations,
0N/A parameterAnnotations,
0N/A annotationDefault);
0N/A }
0N/A
0N/A /** Creates a new java.lang.reflect.Constructor. Access checks as
0N/A per java.lang.reflect.AccessibleObject are not overridden. */
28N/A public Constructor newConstructor(Class<?> declaringClass,
28N/A Class<?>[] parameterTypes,
28N/A Class<?>[] checkedExceptions,
0N/A int modifiers,
0N/A int slot,
0N/A String signature,
0N/A byte[] annotations,
0N/A byte[] parameterAnnotations)
0N/A {
0N/A return langReflectAccess().newConstructor(declaringClass,
0N/A parameterTypes,
0N/A checkedExceptions,
0N/A modifiers,
0N/A slot,
0N/A signature,
0N/A annotations,
0N/A parameterAnnotations);
0N/A }
0N/A
0N/A /** Gets the MethodAccessor object for a java.lang.reflect.Method */
0N/A public MethodAccessor getMethodAccessor(Method m) {
0N/A return langReflectAccess().getMethodAccessor(m);
0N/A }
0N/A
0N/A /** Sets the MethodAccessor object for a java.lang.reflect.Method */
0N/A public void setMethodAccessor(Method m, MethodAccessor accessor) {
0N/A langReflectAccess().setMethodAccessor(m, accessor);
0N/A }
0N/A
0N/A /** Gets the ConstructorAccessor object for a
0N/A java.lang.reflect.Constructor */
0N/A public ConstructorAccessor getConstructorAccessor(Constructor c) {
0N/A return langReflectAccess().getConstructorAccessor(c);
0N/A }
0N/A
0N/A /** Sets the ConstructorAccessor object for a
0N/A java.lang.reflect.Constructor */
0N/A public void setConstructorAccessor(Constructor c,
0N/A ConstructorAccessor accessor)
0N/A {
0N/A langReflectAccess().setConstructorAccessor(c, accessor);
0N/A }
0N/A
0N/A /** Makes a copy of the passed method. The returned method is a
0N/A "child" of the passed one; see the comments in Method.java for
0N/A details. */
0N/A public Method copyMethod(Method arg) {
0N/A return langReflectAccess().copyMethod(arg);
0N/A }
0N/A
0N/A /** Makes a copy of the passed field. The returned field is a
0N/A "child" of the passed one; see the comments in Field.java for
0N/A details. */
0N/A public Field copyField(Field arg) {
0N/A return langReflectAccess().copyField(arg);
0N/A }
0N/A
0N/A /** Makes a copy of the passed constructor. The returned
0N/A constructor is a "child" of the passed one; see the comments
0N/A in Constructor.java for details. */
28N/A public <T> Constructor<T> copyConstructor(Constructor<T> arg) {
0N/A return langReflectAccess().copyConstructor(arg);
0N/A }
0N/A
0N/A //--------------------------------------------------------------------------
0N/A //
0N/A // Routines used by serialization
0N/A //
0N/A //
0N/A
0N/A public Constructor newConstructorForSerialization
28N/A (Class<?> classToInstantiate, Constructor constructorToCall)
0N/A {
0N/A // Fast path
0N/A if (constructorToCall.getDeclaringClass() == classToInstantiate) {
0N/A return constructorToCall;
0N/A }
0N/A
0N/A ConstructorAccessor acc = new MethodAccessorGenerator().
0N/A generateSerializationConstructor(classToInstantiate,
0N/A constructorToCall.getParameterTypes(),
0N/A constructorToCall.getExceptionTypes(),
0N/A constructorToCall.getModifiers(),
0N/A constructorToCall.getDeclaringClass());
0N/A Constructor c = newConstructor(constructorToCall.getDeclaringClass(),
0N/A constructorToCall.getParameterTypes(),
0N/A constructorToCall.getExceptionTypes(),
0N/A constructorToCall.getModifiers(),
0N/A langReflectAccess().
0N/A getConstructorSlot(constructorToCall),
0N/A langReflectAccess().
0N/A getConstructorSignature(constructorToCall),
0N/A langReflectAccess().
0N/A getConstructorAnnotations(constructorToCall),
0N/A langReflectAccess().
0N/A getConstructorParameterAnnotations(constructorToCall));
0N/A setConstructorAccessor(c, acc);
0N/A return c;
0N/A }
0N/A
0N/A //--------------------------------------------------------------------------
0N/A //
0N/A // Internals only below this point
0N/A //
0N/A
0N/A static int inflationThreshold() {
0N/A return inflationThreshold;
0N/A }
0N/A
0N/A /** We have to defer full initialization of this class until after
0N/A the static initializer is run since java.lang.reflect.Method's
0N/A static initializer (more properly, that for
0N/A java.lang.reflect.AccessibleObject) causes this class's to be
0N/A run, before the system properties are set up. */
0N/A private static void checkInitted() {
0N/A if (initted) return;
28N/A AccessController.doPrivileged(
28N/A new PrivilegedAction<Void>() {
28N/A public Void run() {
0N/A // Tests to ensure the system properties table is fully
0N/A // initialized. This is needed because reflection code is
0N/A // called very early in the initialization process (before
0N/A // command-line arguments have been parsed and therefore
0N/A // these user-settable properties installed.) We assume that
0N/A // if System.out is non-null then the System class has been
0N/A // fully initialized and that the bulk of the startup code
0N/A // has been run.
0N/A
0N/A if (System.out == null) {
0N/A // java.lang.System not yet fully initialized
0N/A return null;
0N/A }
0N/A
0N/A String val = System.getProperty("sun.reflect.noInflation");
0N/A if (val != null && val.equals("true")) {
0N/A noInflation = true;
0N/A }
0N/A
0N/A val = System.getProperty("sun.reflect.inflationThreshold");
0N/A if (val != null) {
0N/A try {
0N/A inflationThreshold = Integer.parseInt(val);
0N/A } catch (NumberFormatException e) {
0N/A throw (RuntimeException)
0N/A new RuntimeException("Unable to parse property sun.reflect.inflationThreshold").
0N/A initCause(e);
0N/A }
0N/A }
0N/A
0N/A initted = true;
0N/A return null;
0N/A }
0N/A });
0N/A }
0N/A
0N/A private static LangReflectAccess langReflectAccess() {
0N/A if (langReflectAccess == null) {
0N/A // Call a static method to get class java.lang.reflect.Modifier
0N/A // initialized. Its static initializer will cause
0N/A // setLangReflectAccess() to be called from the context of the
0N/A // java.lang.reflect package.
0N/A Modifier.isPublic(Modifier.PUBLIC);
0N/A }
0N/A return langReflectAccess;
0N/A }
0N/A}