JDK-8281001 : Class::forName(String) defaults to system class loader if the caller is null
  • Type: Sub-task
  • Component: core-libs
  • Sub-Component: java.lang:class_loading
  • Affected Version: 8
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2022-01-31
  • Updated: 2022-06-10
  • Resolved: 2022-06-08
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 19
19 b26Fixed
Related Reports
CSR :  
Description
The current behavior of Class::forName(String className) if invoked via JNI code with no Java frame on the stack will use the boot loader to find class.   In addition, the caller's loader is also used to check against the package access check (that check will be removed in the future.  See JDK-8218203).

JNI FindClass uses the system class loader instead if invoked via JNI invocation interface when there is no associated class loader.

We should re-examine if we should make Class::forName when invoked by JNI code with no caller frame be consistent with JNI FindClass, i.e. use the system class loader if caller is null.

The same behavior should apply to the following caller-sensitive methods related to class loading:
Package::getPackage, Package::getPackages
Runtime::load, Runtime::loadLibrary
System::load, System::loadLibrary
Comments
Changeset: b92ce269 Author: Tim Prinzing <tprinzing@openjdk.org> Committer: Mandy Chung <mchung@openjdk.org> Date: 2022-06-08 16:21:55 +0000 URL: https://git.openjdk.java.net/jdk/commit/b92ce2699b604cff638db583215863da8e253db8
08-06-2022

To reduce redundancy in the null caller tests, created JDK-8287171 Refactor null caller tests to a single directory. The test portion of this issue is waiting for that change.
28-05-2022

I agree that we should keep the existing behavior of Package::getPackage, Package::getPackages, Runtime::load, Runtime::loadLibrary, System::load, System::loadLibrary, i.e. when invoked with null caller, it will default to the boot loader as changing to use a different loader is an incompatible change.
14-05-2022

A pull request was submitted for review. URL: https://git.openjdk.java.net/jdk/pull/8711 Date: 2022-05-14 00:30:00 +0000
14-05-2022

It's not clear to me what the best approach is here, but these are my thoughts: The Class::forName behavior change to match JNI FindClass is a compatible change and seems pretty attractive as it would be expected that Class::forName would give the same behavior as FindClass. The changes to Package::getPackage, Package::getPackages, Runtime::load, Runtime::loadLibrary, System::load, System::loadLibrary are not compatible changes. The methods for loading shared libraries don't seem very attractive to call from JNI where the developer already has access to shared libraries and since the change would be incompatible it seems very unattractive to make that change. The changes to Package seem somewhere in the middle. The Package::getPackage is deprecated and the alternative suggested in the documentation of calling ClassLoader::getDefinedPackage is a better approach making the incompatible changes to Package unattractive. I'm moving forward with changing only Class::forName and piggybacking on the test For JDK-8281006 by adding the additional check.
13-05-2022