jdk/src/java.base/share/classes/sun/reflect/Reflection.java
changeset 38062 430e0a96ef1f
parent 38061 5fe046aef3b9
parent 38060 954c9575f653
child 38064 0e7c67a6ad89
child 38065 025c784d9333
--- a/jdk/src/java.base/share/classes/sun/reflect/Reflection.java	Fri Apr 22 10:19:22 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,425 +0,0 @@
-/*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.reflect;
-
-
-import java.lang.reflect.*;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
-import jdk.internal.HotSpotIntrinsicCandidate;
-import jdk.internal.misc.VM;
-
-/** Common utility routines used by both java.lang and
-    java.lang.reflect */
-
-public class Reflection {
-
-    /** Used to filter out fields and methods from certain classes from public
-        view, where they are sensitive or they may contain VM-internal objects.
-        These Maps are updated very rarely. Rather than synchronize on
-        each access, we use copy-on-write */
-    private static volatile Map<Class<?>,String[]> fieldFilterMap;
-    private static volatile Map<Class<?>,String[]> methodFilterMap;
-
-    static {
-        Map<Class<?>,String[]> map = new HashMap<Class<?>,String[]>();
-        map.put(Reflection.class,
-            new String[] {"fieldFilterMap", "methodFilterMap"});
-        map.put(System.class, new String[] {"security"});
-        map.put(Class.class, new String[] {"classLoader"});
-        fieldFilterMap = map;
-
-        methodFilterMap = new HashMap<>();
-    }
-
-    /** Returns the class of the caller of the method calling this method,
-        ignoring frames associated with java.lang.reflect.Method.invoke()
-        and its implementation. */
-    @CallerSensitive
-    @HotSpotIntrinsicCandidate
-    public static native Class<?> getCallerClass();
-
-    /**
-     * @deprecated This method will be removed in JDK 9.
-     * This method is a private JDK API and retained temporarily for
-     * existing code to run until a replacement API is defined.
-     */
-    @Deprecated
-    public static native Class<?> getCallerClass(int depth);
-
-    /** Retrieves the access flags written to the class file. For
-        inner classes these flags may differ from those returned by
-        Class.getModifiers(), which searches the InnerClasses
-        attribute to find the source-level access flags. This is used
-        instead of Class.getModifiers() for run-time access checks due
-        to compatibility reasons; see 4471811. Only the values of the
-        low 13 bits (i.e., a mask of 0x1FFF) are guaranteed to be
-        valid. */
-    @HotSpotIntrinsicCandidate
-    public static native int getClassAccessFlags(Class<?> c);
-
-
-    public static void ensureMemberAccess(Class<?> currentClass,
-                                          Class<?> memberClass,
-                                          Object target,
-                                          int modifiers)
-        throws IllegalAccessException
-    {
-        if (currentClass == null || memberClass == null) {
-            throw new InternalError();
-        }
-
-        if (!verifyMemberAccess(currentClass, memberClass, target, modifiers)) {
-            throwIllegalAccessException(currentClass, memberClass, target, modifiers);
-        }
-    }
-
-    public static boolean verifyMemberAccess(Class<?> currentClass,
-                                             // Declaring class of field
-                                             // or method
-                                             Class<?> memberClass,
-                                             // May be NULL in case of statics
-                                             Object   target,
-                                             int      modifiers)
-    {
-        // Verify that currentClass can access a field, method, or
-        // constructor of memberClass, where that member's access bits are
-        // "modifiers".
-
-        boolean gotIsSameClassPackage = false;
-        boolean isSameClassPackage = false;
-
-        if (currentClass == memberClass) {
-            // Always succeeds
-            return true;
-        }
-
-        if (!verifyModuleAccess(currentClass, memberClass)) {
-            return false;
-        }
-
-        if (!Modifier.isPublic(getClassAccessFlags(memberClass))) {
-            isSameClassPackage = isSameClassPackage(currentClass, memberClass);
-            gotIsSameClassPackage = true;
-            if (!isSameClassPackage) {
-                return false;
-            }
-        }
-
-        // At this point we know that currentClass can access memberClass.
-
-        if (Modifier.isPublic(modifiers)) {
-            return true;
-        }
-
-        boolean successSoFar = false;
-
-        if (Modifier.isProtected(modifiers)) {
-            // See if currentClass is a subclass of memberClass
-            if (isSubclassOf(currentClass, memberClass)) {
-                successSoFar = true;
-            }
-        }
-
-        if (!successSoFar && !Modifier.isPrivate(modifiers)) {
-            if (!gotIsSameClassPackage) {
-                isSameClassPackage = isSameClassPackage(currentClass,
-                                                        memberClass);
-                gotIsSameClassPackage = true;
-            }
-
-            if (isSameClassPackage) {
-                successSoFar = true;
-            }
-        }
-
-        if (!successSoFar) {
-            return false;
-        }
-
-        if (Modifier.isProtected(modifiers)) {
-            // Additional test for protected members: JLS 6.6.2
-            Class<?> targetClass = (target == null ? memberClass : target.getClass());
-            if (targetClass != currentClass) {
-                if (!gotIsSameClassPackage) {
-                    isSameClassPackage = isSameClassPackage(currentClass, memberClass);
-                    gotIsSameClassPackage = true;
-                }
-                if (!isSameClassPackage) {
-                    if (!isSubclassOf(targetClass, currentClass)) {
-                        return false;
-                    }
-                }
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Returns {@code true} if memberClass's's module exports memberClass's
-     * package to currentClass's module.
-     */
-    public static boolean verifyModuleAccess(Class<?> currentClass,
-                                             Class<?> memberClass) {
-        return verifyModuleAccess(currentClass.getModule(), memberClass);
-    }
-
-    public static boolean verifyModuleAccess(Module currentModule, Class<?> memberClass) {
-        Module memberModule = memberClass.getModule();
-
-        // module may be null during startup (initLevel 0)
-        if (currentModule == memberModule)
-           return true;  // same module (named or unnamed)
-
-        // memberClass may be primitive or array class
-        Class<?> c = memberClass;
-        while (c.isArray()) {
-            c = c.getComponentType();
-        }
-        if (c.isPrimitive())
-            return true;
-
-        // check that memberModule exports the package to currentModule
-        return memberModule.isExported(c.getPackageName(), currentModule);
-    }
-
-    /**
-     * Returns true if two classes in the same package.
-     */
-    private static boolean isSameClassPackage(Class<?> c1, Class<?> c2) {
-        if (c1.getClassLoader() != c2.getClassLoader())
-            return false;
-        while (c1.isArray())
-            c1 = c1.getComponentType();
-        while (c2.isArray())
-            c2 = c2.getComponentType();
-        return Objects.equals(c1.getPackageName(), c2.getPackageName());
-    }
-
-    static boolean isSubclassOf(Class<?> queryClass,
-                                Class<?> ofClass)
-    {
-        while (queryClass != null) {
-            if (queryClass == ofClass) {
-                return true;
-            }
-            queryClass = queryClass.getSuperclass();
-        }
-        return false;
-    }
-
-    // fieldNames must contain only interned Strings
-    public static synchronized void registerFieldsToFilter(Class<?> containingClass,
-                                              String ... fieldNames) {
-        fieldFilterMap =
-            registerFilter(fieldFilterMap, containingClass, fieldNames);
-    }
-
-    // methodNames must contain only interned Strings
-    public static synchronized void registerMethodsToFilter(Class<?> containingClass,
-                                              String ... methodNames) {
-        methodFilterMap =
-            registerFilter(methodFilterMap, containingClass, methodNames);
-    }
-
-    private static Map<Class<?>,String[]> registerFilter(Map<Class<?>,String[]> map,
-            Class<?> containingClass, String ... names) {
-        if (map.get(containingClass) != null) {
-            throw new IllegalArgumentException
-                            ("Filter already registered: " + containingClass);
-        }
-        map = new HashMap<Class<?>,String[]>(map);
-        map.put(containingClass, names);
-        return map;
-    }
-
-    public static Field[] filterFields(Class<?> containingClass,
-                                       Field[] fields) {
-        if (fieldFilterMap == null) {
-            // Bootstrapping
-            return fields;
-        }
-        return (Field[])filter(fields, fieldFilterMap.get(containingClass));
-    }
-
-    public static Method[] filterMethods(Class<?> containingClass, Method[] methods) {
-        if (methodFilterMap == null) {
-            // Bootstrapping
-            return methods;
-        }
-        return (Method[])filter(methods, methodFilterMap.get(containingClass));
-    }
-
-    private static Member[] filter(Member[] members, String[] filteredNames) {
-        if ((filteredNames == null) || (members.length == 0)) {
-            return members;
-        }
-        int numNewMembers = 0;
-        for (Member member : members) {
-            boolean shouldSkip = false;
-            for (String filteredName : filteredNames) {
-                if (member.getName() == filteredName) {
-                    shouldSkip = true;
-                    break;
-                }
-            }
-            if (!shouldSkip) {
-                ++numNewMembers;
-            }
-        }
-        Member[] newMembers =
-            (Member[])Array.newInstance(members[0].getClass(), numNewMembers);
-        int destIdx = 0;
-        for (Member member : members) {
-            boolean shouldSkip = false;
-            for (String filteredName : filteredNames) {
-                if (member.getName() == filteredName) {
-                    shouldSkip = true;
-                    break;
-                }
-            }
-            if (!shouldSkip) {
-                newMembers[destIdx++] = member;
-            }
-        }
-        return newMembers;
-    }
-
-    /**
-     * Tests if the given method is caller-sensitive and the declaring class
-     * is defined by either the bootstrap class loader or platform class loader.
-     */
-    public static boolean isCallerSensitive(Method m) {
-        final ClassLoader loader = m.getDeclaringClass().getClassLoader();
-        if (VM.isSystemDomainLoader(loader) || isExtClassLoader(loader))  {
-            return m.isAnnotationPresent(CallerSensitive.class);
-        }
-        return false;
-    }
-
-    private static boolean isExtClassLoader(ClassLoader loader) {
-        ClassLoader cl = ClassLoader.getSystemClassLoader();
-        while (cl != null) {
-            if (cl.getParent() == null && cl == loader) {
-                return true;
-            }
-            cl = cl.getParent();
-        }
-        return false;
-    }
-
-
-    // true to print a stack trace when IAE is thrown
-    private static volatile boolean printStackWhenAccessFails;
-
-    // true if printStackWhenAccessFails has been initialized
-    private static volatile boolean printStackWhenAccessFailsSet;
-
-    private static void printStackTraceIfNeeded(Throwable e) {
-        if (!printStackWhenAccessFailsSet && VM.initLevel() >= 1) {
-            // can't use method reference here, might be too early in startup
-            PrivilegedAction<Boolean> pa = new PrivilegedAction<Boolean>() {
-                public Boolean run() {
-                    String s;
-                    s = System.getProperty("sun.reflect.debugModuleAccessChecks");
-                    return (s != null && !s.equalsIgnoreCase("false"));
-                }
-            };
-            printStackWhenAccessFails = AccessController.doPrivileged(pa);
-            printStackWhenAccessFailsSet = true;
-        }
-        if (printStackWhenAccessFails) {
-            e.printStackTrace();
-        }
-    }
-
-    /**
-     * Throws IllegalAccessException with the an exception message based on
-     * the access that is denied.
-     */
-    private static void throwIllegalAccessException(Class<?> currentClass,
-                                                    Class<?> memberClass,
-                                                    Object target,
-                                                    int modifiers)
-        throws IllegalAccessException
-    {
-        String currentSuffix = "";
-        String memberSuffix = "";
-        Module m1 = currentClass.getModule();
-        if (m1.isNamed())
-            currentSuffix = " (in " + m1 + ")";
-        Module m2 = memberClass.getModule();
-        if (m2.isNamed())
-            memberSuffix = " (in " + m2 + ")";
-
-        Class<?> c = memberClass;
-        while (c.isArray()) {
-            c = c.getComponentType();
-        }
-        String memberPackageName = c.getPackageName();
-
-        String msg = currentClass + currentSuffix + " cannot access ";
-        if (m2.isExported(memberPackageName, m1)) {
-
-            // module access okay so include the modifiers in the message
-            msg += "a member of " + memberClass + memberSuffix +
-                    " with modifiers \"" + Modifier.toString(modifiers) + "\"";
-
-        } else {
-            // module access failed
-            msg += memberClass + memberSuffix+ " because "
-                   + m2 + " does not export " + memberPackageName;
-            if (m2.isNamed()) msg += " to " + m1;
-        }
-
-        throwIllegalAccessException(msg);
-    }
-
-    /**
-     * Throws IllegalAccessException with the given exception message.
-     */
-    public static void throwIllegalAccessException(String msg)
-        throws IllegalAccessException
-    {
-        IllegalAccessException e = new IllegalAccessException(msg);
-        printStackTraceIfNeeded(e);
-        throw e;
-    }
-
-    /**
-     * Throws InaccessibleObjectException with the given exception message.
-     */
-    public static void throwInaccessibleObjectException(String msg) {
-        InaccessibleObjectException e = new InaccessibleObjectException(msg);
-        printStackTraceIfNeeded(e);
-        throw e;
-    }
-
-}