-
Type:
CSR
-
Resolution: Approved
-
Priority:
P3
-
Component/s: core-libs
-
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
-