1 /*
   2  * Copyright (c) 2001, 2016, 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 jdk.internal.reflect;
  27 
  28 import java.io.Externalizable;
  29 import java.io.ObjectInputStream;
  30 import java.io.ObjectOutputStream;
  31 import java.io.ObjectStreamClass;
  32 import java.io.OptionalDataException;
  33 import java.io.Serializable;
  34 import java.lang.invoke.MethodHandle;
  35 import java.lang.invoke.MethodHandles;
  36 import java.lang.reflect.Field;
  37 import java.lang.reflect.Executable;
  38 import java.lang.reflect.InvocationTargetException;
  39 import java.lang.reflect.Method;
  40 import java.lang.reflect.Constructor;
  41 import java.lang.reflect.Modifier;
  42 import java.security.Permission;
  43 import java.security.PrivilegedAction;
  44 import java.util.Objects;
  45 import java.util.Properties;
  46 
  47 import sun.reflect.misc.ReflectUtil;
  48 import sun.security.action.GetPropertyAction;
  49 
  50 /** <P> The master factory for all reflective objects, both those in
  51     java.lang.reflect (Fields, Methods, Constructors) as well as their
  52     delegates (FieldAccessors, MethodAccessors, ConstructorAccessors).
  53     </P>
  54 
  55     <P> The methods in this class are extremely unsafe and can cause
  56     subversion of both the language and the verifier. For this reason,
  57     they are all instance methods, and access to the constructor of
  58     this factory is guarded by a security check, in similar style to
  59     {@link jdk.internal.misc.Unsafe}. </P>
  60 */
  61 
  62 public class ReflectionFactory {
  63 
  64     private static boolean initted = false;
  65     private static final Permission reflectionFactoryAccessPerm
  66         = new RuntimePermission("reflectionFactoryAccess");
  67     private static final ReflectionFactory soleInstance = new ReflectionFactory();
  68     // Provides access to package-private mechanisms in java.lang.reflect
  69     private static volatile LangReflectAccess langReflectAccess;
  70 
  71     /* Method for static class initializer <clinit>, or null */
  72     private static volatile Method hasStaticInitializerMethod;
  73 
  74     //
  75     // "Inflation" mechanism. Loading bytecodes to implement
  76     // Method.invoke() and Constructor.newInstance() currently costs
  77     // 3-4x more than an invocation via native code for the first
  78     // invocation (though subsequent invocations have been benchmarked
  79     // to be over 20x faster). Unfortunately this cost increases
  80     // startup time for certain applications that use reflection
  81     // intensively (but only once per class) to bootstrap themselves.
  82     // To avoid this penalty we reuse the existing JVM entry points
  83     // for the first few invocations of Methods and Constructors and
  84     // then switch to the bytecode-based implementations.
  85     //
  86     // Package-private to be accessible to NativeMethodAccessorImpl
  87     // and NativeConstructorAccessorImpl
  88     private static boolean noInflation        = false;
  89     private static int     inflationThreshold = 15;
  90 
  91     private ReflectionFactory() {
  92     }
  93 
  94     /**
  95      * A convenience class for acquiring the capability to instantiate
  96      * reflective objects.  Use this instead of a raw call to {@link
  97      * #getReflectionFactory} in order to avoid being limited by the
  98      * permissions of your callers.
  99      *
 100      * <p>An instance of this class can be used as the argument of
 101      * <code>AccessController.doPrivileged</code>.
 102      */
 103     public static final class GetReflectionFactoryAction
 104         implements PrivilegedAction<ReflectionFactory> {
 105         public ReflectionFactory run() {
 106             return getReflectionFactory();
 107         }
 108     }
 109 
 110     /**
 111      * Provides the caller with the capability to instantiate reflective
 112      * objects.
 113      *
 114      * <p> First, if there is a security manager, its
 115      * <code>checkPermission</code> method is called with a {@link
 116      * java.lang.RuntimePermission} with target
 117      * <code>"reflectionFactoryAccess"</code>.  This may result in a
 118      * security exception.
 119      *
 120      * <p> The returned <code>ReflectionFactory</code> object should be
 121      * carefully guarded by the caller, since it can be used to read and
 122      * write private data and invoke private methods, as well as to load
 123      * unverified bytecodes.  It must never be passed to untrusted code.
 124      *
 125      * @exception SecurityException if a security manager exists and its
 126      *             <code>checkPermission</code> method doesn't allow
 127      *             access to the RuntimePermission "reflectionFactoryAccess".  */
 128     public static ReflectionFactory getReflectionFactory() {
 129         SecurityManager security = System.getSecurityManager();
 130         if (security != null) {
 131             // TO DO: security.checkReflectionFactoryAccess();
 132             security.checkPermission(reflectionFactoryAccessPerm);
 133         }
 134         return soleInstance;
 135     }
 136 
 137     //--------------------------------------------------------------------------
 138     //
 139     // Routines used by java.lang.reflect
 140     //
 141     //
 142 
 143     /** Called only by java.lang.reflect.Modifier's static initializer */
 144     public void setLangReflectAccess(LangReflectAccess access) {
 145         langReflectAccess = access;
 146     }
 147 
 148     /**
 149      * Note: this routine can cause the declaring class for the field
 150      * be initialized and therefore must not be called until the
 151      * first get/set of this field.
 152      * @param field the field
 153      * @param override true if caller has overridden accessibility
 154      */
 155     public FieldAccessor newFieldAccessor(Field field, boolean override) {
 156         checkInitted();
 157         return UnsafeFieldAccessorFactory.newFieldAccessor(field, override);
 158     }
 159 
 160     public MethodAccessor newMethodAccessor(Method method) {
 161         checkInitted();
 162 
 163         if (noInflation && !ReflectUtil.isVMAnonymousClass(method.getDeclaringClass())) {
 164             return new MethodAccessorGenerator().
 165                 generateMethod(method.getDeclaringClass(),
 166                                method.getName(),
 167                                method.getParameterTypes(),
 168                                method.getReturnType(),
 169                                method.getExceptionTypes(),
 170                                method.getModifiers());
 171         } else {
 172             NativeMethodAccessorImpl acc =
 173                 new NativeMethodAccessorImpl(method);
 174             DelegatingMethodAccessorImpl res =
 175                 new DelegatingMethodAccessorImpl(acc);
 176             acc.setParent(res);
 177             return res;
 178         }
 179     }
 180 
 181     public ConstructorAccessor newConstructorAccessor(Constructor<?> c) {
 182         checkInitted();
 183 
 184         Class<?> declaringClass = c.getDeclaringClass();
 185         if (Modifier.isAbstract(declaringClass.getModifiers())) {
 186             return new InstantiationExceptionConstructorAccessorImpl(null);
 187         }
 188         if (declaringClass == Class.class) {
 189             return new InstantiationExceptionConstructorAccessorImpl
 190                 ("Can not instantiate java.lang.Class");
 191         }
 192         // Bootstrapping issue: since we use Class.newInstance() in
 193         // the ConstructorAccessor generation process, we have to
 194         // break the cycle here.
 195         if (Reflection.isSubclassOf(declaringClass,
 196                                     ConstructorAccessorImpl.class)) {
 197             return new BootstrapConstructorAccessorImpl(c);
 198         }
 199 
 200         if (noInflation && !ReflectUtil.isVMAnonymousClass(c.getDeclaringClass())) {
 201             return new MethodAccessorGenerator().
 202                 generateConstructor(c.getDeclaringClass(),
 203                                     c.getParameterTypes(),
 204                                     c.getExceptionTypes(),
 205                                     c.getModifiers());
 206         } else {
 207             NativeConstructorAccessorImpl acc =
 208                 new NativeConstructorAccessorImpl(c);
 209             DelegatingConstructorAccessorImpl res =
 210                 new DelegatingConstructorAccessorImpl(acc);
 211             acc.setParent(res);
 212             return res;
 213         }
 214     }
 215 
 216     //--------------------------------------------------------------------------
 217     //
 218     // Routines used by java.lang
 219     //
 220     //
 221 
 222     /** Creates a new java.lang.reflect.Field. Access checks as per
 223         java.lang.reflect.AccessibleObject are not overridden. */
 224     public Field newField(Class<?> declaringClass,
 225                           String name,
 226                           Class<?> type,
 227                           int modifiers,
 228                           int slot,
 229                           String signature,
 230                           byte[] annotations)
 231     {
 232         return langReflectAccess().newField(declaringClass,
 233                                             name,
 234                                             type,
 235                                             modifiers,
 236                                             slot,
 237                                             signature,
 238                                             annotations);
 239     }
 240 
 241     /** Creates a new java.lang.reflect.Method. Access checks as per
 242         java.lang.reflect.AccessibleObject are not overridden. */
 243     public Method newMethod(Class<?> declaringClass,
 244                             String name,
 245                             Class<?>[] parameterTypes,
 246                             Class<?> returnType,
 247                             Class<?>[] checkedExceptions,
 248                             int modifiers,
 249                             int slot,
 250                             String signature,
 251                             byte[] annotations,
 252                             byte[] parameterAnnotations,
 253                             byte[] annotationDefault)
 254     {
 255         return langReflectAccess().newMethod(declaringClass,
 256                                              name,
 257                                              parameterTypes,
 258                                              returnType,
 259                                              checkedExceptions,
 260                                              modifiers,
 261                                              slot,
 262                                              signature,
 263                                              annotations,
 264                                              parameterAnnotations,
 265                                              annotationDefault);
 266     }
 267 
 268     /** Creates a new java.lang.reflect.Constructor. Access checks as
 269         per java.lang.reflect.AccessibleObject are not overridden. */
 270     public Constructor<?> newConstructor(Class<?> declaringClass,
 271                                          Class<?>[] parameterTypes,
 272                                          Class<?>[] checkedExceptions,
 273                                          int modifiers,
 274                                          int slot,
 275                                          String signature,
 276                                          byte[] annotations,
 277                                          byte[] parameterAnnotations)
 278     {
 279         return langReflectAccess().newConstructor(declaringClass,
 280                                                   parameterTypes,
 281                                                   checkedExceptions,
 282                                                   modifiers,
 283                                                   slot,
 284                                                   signature,
 285                                                   annotations,
 286                                                   parameterAnnotations);
 287     }
 288 
 289     /** Gets the MethodAccessor object for a java.lang.reflect.Method */
 290     public MethodAccessor getMethodAccessor(Method m) {
 291         return langReflectAccess().getMethodAccessor(m);
 292     }
 293 
 294     /** Sets the MethodAccessor object for a java.lang.reflect.Method */
 295     public void setMethodAccessor(Method m, MethodAccessor accessor) {
 296         langReflectAccess().setMethodAccessor(m, accessor);
 297     }
 298 
 299     /** Gets the ConstructorAccessor object for a
 300         java.lang.reflect.Constructor */
 301     public ConstructorAccessor getConstructorAccessor(Constructor<?> c) {
 302         return langReflectAccess().getConstructorAccessor(c);
 303     }
 304 
 305     /** Sets the ConstructorAccessor object for a
 306         java.lang.reflect.Constructor */
 307     public void setConstructorAccessor(Constructor<?> c,
 308                                        ConstructorAccessor accessor)
 309     {
 310         langReflectAccess().setConstructorAccessor(c, accessor);
 311     }
 312 
 313     /** Makes a copy of the passed method. The returned method is a
 314         "child" of the passed one; see the comments in Method.java for
 315         details. */
 316     public Method copyMethod(Method arg) {
 317         return langReflectAccess().copyMethod(arg);
 318     }
 319 
 320     /** Makes a copy of the passed method. The returned method is NOT
 321      * a "child" but a "sibling" of the Method in arg. Should only be
 322      * used on non-root methods. */
 323     public Method leafCopyMethod(Method arg) {
 324         return langReflectAccess().leafCopyMethod(arg);
 325     }
 326 
 327 
 328     /** Makes a copy of the passed field. The returned field is a
 329         "child" of the passed one; see the comments in Field.java for
 330         details. */
 331     public Field copyField(Field arg) {
 332         return langReflectAccess().copyField(arg);
 333     }
 334 
 335     /** Makes a copy of the passed constructor. The returned
 336         constructor is a "child" of the passed one; see the comments
 337         in Constructor.java for details. */
 338     public <T> Constructor<T> copyConstructor(Constructor<T> arg) {
 339         return langReflectAccess().copyConstructor(arg);
 340     }
 341 
 342     /** Gets the byte[] that encodes TypeAnnotations on an executable.
 343      */
 344     public byte[] getExecutableTypeAnnotationBytes(Executable ex) {
 345         return langReflectAccess().getExecutableTypeAnnotationBytes(ex);
 346     }
 347 
 348     //--------------------------------------------------------------------------
 349     //
 350     // Routines used by serialization
 351     //
 352     //
 353 
 354     public final Constructor<?> newConstructorForExternalization(Class<?> cl) {
 355         if (!Externalizable.class.isAssignableFrom(cl)) {
 356             return null;
 357         }
 358         try {
 359             Constructor<?> cons = cl.getConstructor();
 360             cons.setAccessible(true);
 361             return cons;
 362         } catch (NoSuchMethodException ex) {
 363             return null;
 364         }
 365     }
 366 
 367     public final Constructor<?> newConstructorForSerialization(Class<?> cl) {
 368         Class<?> initCl = cl;
 369         while (Serializable.class.isAssignableFrom(initCl)) {
 370             if ((initCl = initCl.getSuperclass()) == null) {
 371                 return null;
 372             }
 373         }
 374         Constructor<?> constructorToCall;
 375         try {
 376             constructorToCall = initCl.getDeclaredConstructor();
 377             int mods = constructorToCall.getModifiers();
 378             if ((mods & Modifier.PRIVATE) != 0 ||
 379                     ((mods & (Modifier.PUBLIC | Modifier.PROTECTED)) == 0 &&
 380                             !packageEquals(cl, initCl))) {
 381                 return null;
 382             }
 383         } catch (NoSuchMethodException ex) {
 384             return null;
 385         }
 386 
 387         ConstructorAccessor acc = new MethodAccessorGenerator().
 388             generateSerializationConstructor(cl,
 389                                              constructorToCall.getParameterTypes(),
 390                                              constructorToCall.getExceptionTypes(),
 391                                              constructorToCall.getModifiers(),
 392                                              constructorToCall.getDeclaringClass());
 393         Constructor<?> c = newConstructor(constructorToCall.getDeclaringClass(),
 394                                           constructorToCall.getParameterTypes(),
 395                                           constructorToCall.getExceptionTypes(),
 396                                           constructorToCall.getModifiers(),
 397                                           langReflectAccess().
 398                                           getConstructorSlot(constructorToCall),
 399                                           langReflectAccess().
 400                                           getConstructorSignature(constructorToCall),
 401                                           langReflectAccess().
 402                                           getConstructorAnnotations(constructorToCall),
 403                                           langReflectAccess().
 404                                           getConstructorParameterAnnotations(constructorToCall));
 405         setConstructorAccessor(c, acc);
 406         c.setAccessible(true);
 407         return c;
 408     }
 409 
 410     public final MethodHandle readObjectForSerialization(Class<?> cl) {
 411         return findReadWriteObjectForSerialization(cl, "readObject", ObjectInputStream.class);
 412     }
 413 
 414     public final MethodHandle readObjectNoDataForSerialization(Class<?> cl) {
 415         return findReadWriteObjectForSerialization(cl, "readObjectNoData", ObjectInputStream.class);
 416     }
 417 
 418     public final MethodHandle writeObjectForSerialization(Class<?> cl) {
 419         return findReadWriteObjectForSerialization(cl, "writeObject", ObjectOutputStream.class);
 420     }
 421 
 422     private final MethodHandle findReadWriteObjectForSerialization(Class<?> cl,
 423                                                                    String methodName,
 424                                                                    Class<?> streamClass) {
 425         if (!Serializable.class.isAssignableFrom(cl)) {
 426             return null;
 427         }
 428 
 429         try {
 430             Method meth = cl.getDeclaredMethod(methodName, streamClass);
 431             int mods = meth.getModifiers();
 432             if (meth.getReturnType() != Void.TYPE ||
 433                     Modifier.isStatic(mods) ||
 434                     !Modifier.isPrivate(mods)) {
 435                 return null;
 436             }
 437             meth.setAccessible(true);
 438             return MethodHandles.lookup().unreflect(meth);
 439         } catch (NoSuchMethodException ex) {
 440             return null;
 441         } catch (IllegalAccessException ex1) {
 442             throw new InternalError("Error", ex1);
 443         }
 444     }
 445 
 446     /**
 447      * Returns a MethodHandle for {@code writeReplace} on the serializable class
 448      * or null if no match found.
 449      * @param cl a serializable class
 450      * @returnss the {@code writeReplace} MethodHandle or {@code null} if not found
 451      */
 452     public final MethodHandle writeReplaceForSerialization(Class<?> cl) {
 453         return getReplaceResolveForSerialization(cl, "writeReplace");
 454     }
 455 
 456     /**
 457      * Returns a MethodHandle for {@code readResolve} on the serializable class
 458      * or null if no match found.
 459      * @param cl a serializable class
 460      * @returns the {@code writeReplace} MethodHandle or {@code null} if not found
 461      */
 462     public final MethodHandle readResolveForSerialization(Class<?> cl) {
 463         return getReplaceResolveForSerialization(cl, "readResolve");
 464     }
 465 
 466     /**
 467      * Lookup readResolve or writeReplace on a class with specified
 468      * signature constraints.
 469      * @param cl a serializable class
 470      * @param methodName the method name to find
 471      * @returns a MethodHandle for the method or {@code null} if not found or
 472      *       has the wrong signature.
 473      */
 474     private MethodHandle getReplaceResolveForSerialization(Class<?> cl,
 475                                                            String methodName) {
 476         if (!Serializable.class.isAssignableFrom(cl)) {
 477             return null;
 478         }
 479 
 480         Class<?> defCl = cl;
 481         while (defCl != null) {
 482             try {
 483                 Method m = defCl.getDeclaredMethod(methodName);
 484                 if (m.getReturnType() != Object.class) {
 485                     return null;
 486                 }
 487                 int mods = m.getModifiers();
 488                 if (Modifier.isStatic(mods) | Modifier.isAbstract(mods)) {
 489                     return null;
 490                 } else if (Modifier.isPublic(mods) | Modifier.isProtected(mods)) {
 491                     // fall through
 492                 } else if (Modifier.isPrivate(mods) && (cl != defCl)) {
 493                     return null;
 494                 } else if (!packageEquals(cl, defCl)) {
 495                     return null;
 496                 }
 497                 try {
 498                     // Normal return
 499                     m.setAccessible(true);
 500                     return MethodHandles.lookup().unreflect(m);
 501                 } catch (IllegalAccessException ex0) {
 502                     // setAccessible should prevent IAE
 503                     throw new InternalError("Error", ex0);
 504                 }
 505             } catch (NoSuchMethodException ex) {
 506                 defCl = defCl.getSuperclass();
 507             }
 508         }
 509         return null;
 510     }
 511 
 512     /**
 513      * Returns true if the given class defines a static initializer method,
 514      * false otherwise.
 515      */
 516     public final boolean hasStaticInitializerForSerialization(Class<?> cl) {
 517         Method m = hasStaticInitializerMethod;
 518         if (m == null) {
 519             try {
 520                 m = ObjectStreamClass.class.getDeclaredMethod("hasStaticInitializer",
 521                         new Class<?>[]{Class.class});
 522                 m.setAccessible(true);
 523                 hasStaticInitializerMethod = m;
 524             } catch (NoSuchMethodException ex) {
 525                 throw new InternalError("No such method hasStaticInitializer on "
 526                         + ObjectStreamClass.class, ex);
 527             }
 528         }
 529         try {
 530             return (Boolean) m.invoke(null, cl);
 531         } catch (InvocationTargetException | IllegalAccessException ex) {
 532             throw new InternalError("Exception invoking hasStaticInitializer", ex);
 533         }
 534     }
 535 
 536     /**
 537      * Return the accessible constructor for OptionalDataException signaling eof.
 538      * @returns the eof constructor for OptionalDataException
 539      */
 540     public final Constructor<OptionalDataException> newOptionalDataExceptionForSerialization() {
 541         try {
 542             Constructor<OptionalDataException> boolCtor =
 543                     OptionalDataException.class.getDeclaredConstructor(Boolean.TYPE);
 544             boolCtor.setAccessible(true);
 545             return boolCtor;
 546         } catch (NoSuchMethodException ex) {
 547             throw new InternalError("Constructor not found", ex);
 548         }
 549     }
 550 
 551     //--------------------------------------------------------------------------
 552     //
 553     // Internals only below this point
 554     //
 555 
 556     static int inflationThreshold() {
 557         return inflationThreshold;
 558     }
 559 
 560     /** We have to defer full initialization of this class until after
 561         the static initializer is run since java.lang.reflect.Method's
 562         static initializer (more properly, that for
 563         java.lang.reflect.AccessibleObject) causes this class's to be
 564         run, before the system properties are set up. */
 565     private static void checkInitted() {
 566         if (initted) return;
 567 
 568         // Tests to ensure the system properties table is fully
 569         // initialized. This is needed because reflection code is
 570         // called very early in the initialization process (before
 571         // command-line arguments have been parsed and therefore
 572         // these user-settable properties installed.) We assume that
 573         // if System.out is non-null then the System class has been
 574         // fully initialized and that the bulk of the startup code
 575         // has been run.
 576 
 577         if (System.out == null) {
 578             // java.lang.System not yet fully initialized
 579             return;
 580         }
 581 
 582         Properties props = GetPropertyAction.privilegedGetProperties();
 583         String val = props.getProperty("sun.reflect.noInflation");
 584         if (val != null && val.equals("true")) {
 585             noInflation = true;
 586         }
 587 
 588         val = props.getProperty("sun.reflect.inflationThreshold");
 589         if (val != null) {
 590             try {
 591                 inflationThreshold = Integer.parseInt(val);
 592             } catch (NumberFormatException e) {
 593                 throw new RuntimeException("Unable to parse property sun.reflect.inflationThreshold", e);
 594             }
 595         }
 596 
 597         initted = true;
 598     }
 599 
 600     private static LangReflectAccess langReflectAccess() {
 601         if (langReflectAccess == null) {
 602             // Call a static method to get class java.lang.reflect.Modifier
 603             // initialized. Its static initializer will cause
 604             // setLangReflectAccess() to be called from the context of the
 605             // java.lang.reflect package.
 606             Modifier.isPublic(Modifier.PUBLIC);
 607         }
 608         return langReflectAccess;
 609     }
 610 
 611     /**
 612      * Returns true if classes are defined in the classloader and same package, false
 613      * otherwise.
 614      * @param cl1 a class
 615      * @param cl2 another class
 616      * @returns true if the two classes are in the same classloader and package
 617      */
 618     private static boolean packageEquals(Class<?> cl1, Class<?> cl2) {
 619         return cl1.getClassLoader() == cl2.getClassLoader() &&
 620                 Objects.equals(cl1.getPackage(), cl2.getPackage());
 621     }
 622 
 623 }