diff -r a5da0277d9bb -r b16e8a886fc3 src/java.base/share/classes/jdk/internal/reflect/Reflection.java --- a/src/java.base/share/classes/jdk/internal/reflect/Reflection.java Sat Apr 06 21:05:58 2019 +0800 +++ b/src/java.base/share/classes/jdk/internal/reflect/Reflection.java Sat Apr 06 21:16:40 2019 +0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2019, 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 @@ -122,6 +122,9 @@ Class targetClass, int modifiers) { + Objects.requireNonNull(currentClass); + Objects.requireNonNull(memberClass); + if (currentClass == memberClass) { // Always succeeds return true; @@ -201,6 +204,22 @@ return true; } + /* + * Verify if a member is public and memberClass is a public type + * in a package that is unconditionally exported and + * return {@code true}if it is granted. + * + * @param memberClass the declaring class of the member being accessed + * @param modifiers the member's access modifiers + * @return {@code true} if the member is public and in a publicly accessible type + */ + public static boolean verifyPublicMemberAccess(Class memberClass, int modifiers) { + Module m = memberClass.getModule(); + return Modifier.isPublic(modifiers) + && m.isExported(memberClass.getPackageName()) + && Modifier.isPublic(Reflection.getClassAccessFlags(memberClass)); + } + /** * Returns {@code true} if memberClass's module exports memberClass's * package to currentModule. @@ -325,8 +344,10 @@ Class memberClass, Class targetClass, int modifiers) - throws IllegalAccessException { + if (currentClass == null) + return newIllegalAccessException(memberClass, modifiers); + String currentSuffix = ""; String memberSuffix = ""; Module m1 = currentClass.getModule(); @@ -356,6 +377,36 @@ } /** + * Returns an IllegalAccessException with an exception message where + * there is no caller frame. + */ + private static IllegalAccessException newIllegalAccessException(Class memberClass, + int modifiers) + { + String memberSuffix = ""; + Module m2 = memberClass.getModule(); + if (m2.isNamed()) + memberSuffix = " (in " + m2 + ")"; + + String memberPackageName = memberClass.getPackageName(); + + String msg = "JNI attached native thread (null caller frame) cannot access "; + if (m2.isExported(memberPackageName)) { + + // 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; + } + + return new IllegalAccessException(msg); + } + + /** * Returns true if {@code currentClass} and {@code memberClass} * are nestmates - that is, if they have the same nesthost as * determined by the VM.