JDK-8240338 : Lookup::defineClass should link the class to match the specification
  • Type: CSR
  • Component: core-libs
  • Sub-Component: java.lang.invoke
  • Priority: P3
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 15
  • Submitted: 2020-03-02
  • Updated: 2020-03-27
  • Resolved: 2020-03-27
Related Reports
CSR :  
Relates :  
Description
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
```



Comments
Moving to Approved; please consider adding a release note.
27-03-2020