--- 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.