--- old/src/java.base/share/classes/jdk/internal/reflect/Reflection.java 2017-03-19 18:36:28.732219720 +0100 +++ new/src/java.base/share/classes/jdk/internal/reflect/Reflection.java 2017-03-19 18:36:28.612221767 +0100 @@ -104,39 +104,43 @@ int modifiers) throws IllegalAccessException { - if (currentClass == null || memberClass == null) { - throw new InternalError(); - } - if (!verifyMemberAccess(currentClass, memberClass, targetClass, modifiers)) { throwIllegalAccessException(currentClass, memberClass, targetClass, modifiers); } } /** - * Verify access to a member, returning {@code false} if no access + * Verify access to a member and return {@code true} if it is granted. + * + * @param currentClass the class performing the access + * @param memberClass the declaring class of the member being accessed + * @param targetClass the class of target object if accessing instance + * field or method; + * or the declaring class if accessing constructor; + * or null if accessing static field or method + * @param modifiers the member's access modifiers + * @return {@code true} if access to member is granted */ public static boolean verifyMemberAccess(Class currentClass, Class memberClass, Class targetClass, 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; + Objects.requireNonNull(currentClass, "currentClass"); + Objects.requireNonNull(memberClass, "memberClass"); if (currentClass == memberClass) { // Always succeeds return true; } - if (!verifyModuleAccess(currentClass, memberClass)) { + if (!verifyModuleAccess(currentClass.getModule(), memberClass)) { return false; } + boolean gotIsSameClassPackage = false; + boolean isSameClassPackage = false; + if (!Modifier.isPublic(getClassAccessFlags(memberClass))) { isSameClassPackage = isSameClassPackage(currentClass, memberClass); gotIsSameClassPackage = true; @@ -197,19 +201,18 @@ /** * Returns {@code true} if memberClass's's module exports memberClass's - * package to currentClass's module. + * package to currentModule. */ - public static boolean verifyModuleAccess(Class currentClass, - Class memberClass) { - return verifyModuleAccess(currentClass.getModule(), memberClass); - } - public static boolean verifyModuleAccess(Module currentModule, Class memberClass) { + if (VM.isModuleSystemInited()) + Objects.requireNonNull(currentModule, "currentModule"); + Objects.requireNonNull(memberClass, "memberClass"); + Module memberModule = memberClass.getModule(); - // module may be null during startup (initLevel 0) + // module may be null during startup (initLevel < VM.MODULE_SYSTEM_INITED) if (currentModule == memberModule) - return true; // same module (named or unnamed) + return true; // same module (named or unnamed) or both are null String pkg = memberClass.getPackageName(); boolean allowed = memberModule.isExported(pkg, currentModule); @@ -378,11 +381,13 @@ /** * Throws IllegalAccessException with the an exception message based on - * the access that is denied. + * the access that is denied. This method throws meaningful exception only + * when {@link #verifyMemberAccess(Class, Class, Class, int)} returns false + * for the same parameters. */ - private static void throwIllegalAccessException(Class currentClass, + public static void throwIllegalAccessException(Class currentClass, Class memberClass, - Object target, + Class targetClass, int modifiers) throws IllegalAccessException {