JDK-8235521 : Replacement API for Unsafe::ensureClassInitialized
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.lang.invoke
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2019-12-06
  • Updated: 2020-10-05
  • Resolved: 2020-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 15
15 b27Fixed
Related Reports
CSR :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
A class may also be initialized as a result of execution of other bytecodes such as getstatic, new, putstatic, invokestatic etc as specified in JVMS 5.5.

`Class::forName` and `Unsafe::ensureClassInitialized` are existing workaround to initialize a Class.  It's cumbersome to use Class::forName to initialize a class and many JDK classes use `Unsafe::ensureClassInitialized` rather than Class::forName to initialize a class.

One typical use of `Unsafe::ensureClassInitialized` to force class initialization is to enable JIT inlining as well as the method handle can avoid the class initialization barrier. 

The other use of `Unsafe::ensureClassInitialized` to force class initialization  is to ensure that private static members are initialized and published to other classes (outside its nest) to access, e.g. shared secrets.
Comments
[~dlong] sorry about that. Is the given clazz accessible to jdk.internal.vm.compiler module? If so, it can call MethodHandles.privateLookupIn(clazz, MethodHandles.lookup()) to get a Lookup object on clazz with private access.
12-06-2020

[~mchung] This probably should have been reviewed by some Graal/compiler folks so it would be on our radar to port upstream to Graal. I see that the change in /jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeClass.java can now throw an exception. Is there a way to do a privileged lookup to avoid the exception?
12-06-2020

URL: https://hg.openjdk.java.net/jdk/jdk/rev/ba476db59099 User: mchung Date: 2020-06-08 23:56:22 +0000
08-06-2020

Mandy: Right, we need control over the classloading machinery itself, so the name "ensureLoaded" is good. Since we do not actually need LockSupport to be initialized, we can just keep using the idiom (in a clinit) Class<?> ensureLoaded = LockSupport.class;
26-05-2020

`LockSupport.class` is compiled to as `ldc` which causes symbolic resolution and the class is loaded which seems to be what you want from the variable name `ensureLoaded`. But the class is not initialized. This RFE is about invoking the <clinit>.
26-05-2020

We've been using the idiom Class<?> ensureLoaded = LockSupport.class; Is that wrong? If so, what should we be doing instead? Probably that behavior needs to be maintained - jdk code is not the only code that does this.
07-12-2019

This enhancement should take `Lookup::defineClass` and `Lookup::defineHiddenClass` into consideration. See https://mail.openjdk.java.net/pipermail/valhalla-dev/2019-December/006644.html
06-12-2019