Save This Page
Home » openjdk-7 » sun » reflect » [javadoc | source]
    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   }

Save This Page
Home » openjdk-7 » sun » reflect » [javadoc | source]