Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8245871

Define Lookup::ensureInitialized as a replacement API for Unsafe::ensureClassInitialized

    XMLWordPrintable

    Details

    • Type: CSR
    • Status: Closed
    • Priority: P3
    • Resolution: Approved
    • Fix Version/s: 15
    • Component/s: core-libs
    • Labels:
      None
    • Subcomponent:
    • Compatibility Risk:
      minimal
    • Interface Kind:
      Java API
    • Scope:
      SE

      Description

      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) {
      

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              mchung Mandy Chung
              Reporter:
              mchung Mandy Chung
              Reviewed By:
              Alan Bateman, Chris Hegarty, John Rose, Mark Reinhold, Paul Sandoz
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: