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