-
CSR
-
Resolution: Approved
-
P3
-
None
-
behavioral
-
minimal
-
-
Java API
-
SE
Summary
Clarify the behavior of java.lang.reflect.AccessibleObject::setAccessible
and trySetAccessible
APIs when invoked by JNI code with no Java frames on the stack that it only allows access to public member of a public type that is unconditionally exported per the access check as described in the class specification.
Problem
The current implementation of AccessibleObject::setAccessible
and trySetAccessible
throws NPE when invoked by JNI code with no Java class on the stack. The behavior of AccessibleObject::setAccessible
and trySetAccessible
should be consistent with the access check.
The class spec of AccessibleObject
has been updated in Java 13 (JDK-8221618) that JNI code with no Java class on the stack can only access public members of a public type that is in a package that is exported unconditionally.
Solution
Fix the implementation of setAccessible
and trySetAccessible
to allow setting the accessible flag on public members of a public type that is exported conditionally when invoked by a native thread attaches to the VM with no caller frame. Also clarify the specification of canAccess
, setAccessible
and trySetAccessible
w.r.t. when invoked by JNI code with no Java frame on the stack.
Specification
AccessibleObject::setAccessible(boolean)
* open module. </li>
* </ul>
*
+ * <p> This method may be used by <a href="{@docRoot}/../specs/jni/index.html">JNI code</a>
+ * with no caller class on the stack to enable access to a {@link Member member}
+ * of {@link Member#getDeclaringClass() declaring class} {@code D} if and only if:
+ * <ul>
+ * <li> The member is {@code public} and {@code D} is {@code public} in
+ * a package that the module containing {@code D} {@link
+ * Module#isExported(String,Module) exports} unconditionally. </li>
+ * </ul>
+ *
* <p> This method cannot be used to enable access to private members,
* members with default (package) access, protected instance members, or
* protected constructors when the declaring class is in a different module
AccessibleObject::trySetAccessible
+ * <p> If this method is invoked by <a href="{@docRoot}/../specs/jni/index.html">JNI code</a>
+ * with no caller class on the stack, the {@code accessible} flag can
+ * only be set if the member and the declaring class are public, and
+ * the class is in a package that is exported unconditionally. </p>
+ *
AccessibleObject::canAccess
- * with the variation noted in the class description. </p>
+ * with the variation noted in the class description.
+ * If this method is invoked by <a href="{@docRoot}/../specs/jni/index.html">JNI code</a>
+ * with no caller class on the stack, this method returns {@code true}
+ * if the member and the declaring class are public, and the class is in
+ * a package that is exported unconditionally. </p>
- csr of
-
JDK-8221642 AccessibleObject::setAccessible throws NPE when invoked by JNI code with no java frame on stack
-
- Closed
-