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