--- a/jdk/src/java.base/share/classes/sun/reflect/Reflection.java Fri Apr 15 16:19:14 2016 +0100
+++ /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;
- }
-
-}