Review Request: 8221530: Caller sensitive methods not handling caller = null when invoked by JNI code with no java frames on stack

Mandy Chung mandy.chung at
Wed Mar 27 23:17:04 UTC 2019

This is to fix a regression introduced in JDK 12 by JDK-8206240.
This impacts only native application that creates JVM via JNI
and also invokes Field::getField (or other reflection API) via
JNI that triggers reflection access check against the caller class.
The regression happens only when there is no caller frame, i.e.
when a native thread attaches to JVM e.g. custom launcher.

It's unclear why the native code invokes Field::getField via JNI
to get the value of `java.lang.Integer::TYPE`.  Alternatively it could
call GetFieldID to get jfieldID of that field and then GetObjectField
if this has to be done in JNI (perhaps bypass encapsulation?).

There is no clear semantics what reflection should behave when there
is no caller frame.   Previously, JNI call to access 
field happens to work since it is called very early at runtime and
AccessibleObject::cache is null and happens that cache == caller == null.

The proposed fix is to perform proper access check.  When there is no
caller frame, it only allows to access to public members of a public type
in an unconditional exported API package.

If a native thread attaches to the VM and attempts to access a non-public
member or a public member in a non-exported type e.g. 
it will throw IAE whereas the access check succeeds in JDK 11. It is
illegal to access a non-exported type.   I think the compatibility risk
should be low as this only happens to a native code creating its VM and
calling reflection to access a member in a non-exported type. There is
no change to the behavior of JNI GetFieldID and GetObjectField.


I will create a CSR.


More information about the core-libs-dev mailing list