-
CSR
-
Resolution: Approved
-
P3
-
None
-
minimal
-
Java API
-
SE
Summary
Define java.lang.invoke.MethodHandles.Lookup::ensureInitialized
as a replacement API for sun.misc.Unsafe::ensureClassInitialized
Problem
Class initialization will happen as specified in JLS 12.4 and JVMS 5.5 that involves accessing its member.
An existing programmatic way to initialize a class is Class::forName
but that requires to know the name of the class and a class loader that can find such class. This may not always be feasible for frameworks.
Solution
Add Lookup::ensureInitialized
method to initialize the given class if the lookup has the access to the class to be initialized.
Class::ensureInitialized
was another option considered. It should be caller sensitive in order to ensure the caller has the proper access to this class. This alternative may not work for frameworks which have no access to user classes. It would have to fallback to Class::forName
limited solution.
OTOH a framework can use Lookup::privateLookupIn
to access a class in another module if the module authorizes it by opening the packages for it to access. Or a user can produce a less privileged lookup by Lookup::dropLookupMode
and pass it to the framework.
Specification
Add the ensureInitialized
method in java.lang.invoke.MethodHandles.Lookup
:
/**
* Ensures that {@code targetClass} has been initialized. The class
* to be initialized must be {@linkplain #accessClass accessible}
* to this {@code Lookup} object. This method causes {@code targetClass}
* to be initialized if it has not been already initialized,
* as specified in JVMS {@jvms 5.5}.
*
* @param targetClass the class to be initialized
* @return {@code targetClass} that has been initialized
*
* @throws IllegalArgumentException if {@code targetClass} is a primitive type or {@code void}
* or array class
* @throws IllegalAccessException if {@code targetClass} is not
* {@linkplain #accessClass accessible} to this lookup
* @throws ExceptionInInitializerError if the class initialization provoked
* by this method fails
* @throws SecurityException if a security manager is present and it
* <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
* @since 15
* @jvms 5.5 Initialization
*/
public Class<?> ensureClassInitialized(Class<?> targetClass) throws IllegalAccessException {
Deprecate sun.misc.Unsafe::ensureClassInitialized
and sun.misc.Unsafe::shouldBeInitialized
method for removal.
@@ -710,7 +710,11 @@
* Ensures the given class has been initialized. This is often
* needed in conjunction with obtaining the static field base of a
* class.
+ *
+ * @deprecated Use the {@link java.lang.invoke.MethodHandles.Lookup#ensureInitialized(Class)}
+ * method instead.
*/
+ @Deprecated(since = "15", forRemoval = true)
@ForceInline
public void ensureClassInitialized(Class<?> c) {
theInternalUnsafe.ensureClassInitialized(c);
+ *
+ * @deprecated No replacement API for this method. As multiple threads
+ * may be trying to initialize the same class or interface at the same time.
+ * The only reliable result returned by this method is {@code false}
+ * indicating that the given class has been initialized. Instead, simply
+ * call {@link java.lang.invoke.MethodHandles.Lookup#ensureInitialized(Class)}
+ * that does nothing if the given class has already been initialized.
+ * This method is subject to removal in a future version of JDK.
+ *
* @return false only if a call to {@code ensureClassInitialized} would have no effect
+ *
*/
+ @Deprecated(since = "15", forRemoval = true)
@ForceInline
public boolean shouldBeInitialized(Class<?> c) {
- csr of
-
JDK-8235521 Replacement API for Unsafe::ensureClassInitialized
- Resolved
- relates to
-
JDK-4993813 (reflect) Need a way to force a class to be initialized.
- Closed