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

Lookup::defineClass should link the class to match the specification

XMLWordPrintable

    • behavioral
    • low
    • Hide
      `Lookup::defineClass` may throw LinkageError in this release when defining a class that fails linking while it succeeds in defining such class in Java SE 14.

      Typically usage of this API is to dynamically generate a class and then execute the code right away. It should be rare that the newly created class never gets executed. Changing the implementation linking the class is expected to have low compatibility risk.
      Show
      `Lookup::defineClass` may throw LinkageError in this release when defining a class that fails linking while it succeeds in defining such class in Java SE 14. Typically usage of this API is to dynamically generate a class and then execute the code right away. It should be rare that the newly created class never gets executed. Changing the implementation linking the class is expected to have low compatibility risk.
    • Java API
    • SE

      Summary

      Change the implementation of Lookup::defineClass to link the class matching the specification

      Problem

      The spec of Lookup::defineClass throws LinkageError:

      LinkageError - if the class is malformed (ClassFormatError), cannot be verified (VerifyError), is already defined, or another linkage error occurs

      VerifyError clearly indicates that this class is verified. However, the current implementation does not link the class.

      Lookup::defineClass was added in Java SE 9 as a public supported API to replace the calls to the protected ClassLoader::defineClass method which frameworks have been suppressing the language access check via setAccessible.

      Framework libraries use Lookup::defineClass to create a class generated dynamically (that cannot be found from the class loader) and typically executes code from the newly created class. It's expected that a framework will generate classes that can link and run.

      Solution

      Fix the implementation to link the newly created class matching the specification.

      There are a few frameworks migrating to use Lookup::defineClass. Framework libraries use Lookup::defineClass to create a class generated dynamically (that cannot be found from the class loader) and typically executes code from the newly created class, i.e. the code generated can link and run. The compatibility risk of fixing the implementation to match the specification is considered low.

      In addition, this will be consistent with the proposed Lookup::defineHiddenClass API (JDK-8238359) that links the newly created class.

      Specification

      Lookup::defineClass spec is clarifed that the newly created class is linked.

      diff --git a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java
      --- a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java
      +++ b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java
      @@ -1623,7 +1623,7 @@
               }
      
               /**
      -         * Creates a class or interface from {@code bytes}
      +         * Creates and links a class or interface from {@code bytes}
                * with the same class loader and in the same runtime package and
                * {@linkplain java.security.ProtectionDomain protection domain} as this lookup's
                * {@linkplain #lookupClass() lookup class} as if calling

            mchung Mandy Chung
            mchung Mandy Chung
            Chris Hegarty, Paul Sandoz
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: