JDK-8243093 : Release Note: JEP 371: Hidden Classes
  • Type: Sub-task
  • Component: core-libs
  • Sub-Component: java.lang.invoke
  • Affected Version: 15
  • Priority: P4
  • Status: Closed
  • Resolution: Delivered
  • Submitted: 2020-04-17
  • Updated: 2021-05-14
  • Resolved: 2020-08-04
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
15Resolved
Description
[JEP 371](https://openjdk.java.net/jeps/371) introduces hidden classes in Java 15.  Hidden classes have the following implications to existing code:

1. `Class::getName` traditionally returns a binary name, but for a hidden class it returns a string that contains an ASCII forward slash (`/`) and is therefore not a binary name. Programs that assume the returned string is a binary name might need to be updated to handle hidden classes. That said, the longstanding practice of `Unsafe::defineAnonymousClass` was to define classes whose names were not binary names, so some programs may already handle such names successfully.

2. `Class::descriptorString` and `MethodType::descriptorString` returns a string that contains a ASCII dot (`.`)  for a hidden class and therefore is not a type descriptor conforming to JVMS 4.3.   Programs that assume the returned string is a type descriptor that conforms to JVMS 4.3 might need to be updated to handle hidden classes. 

3. `Class::getNestMembers` is changed to not throw an exception when it fails to validate a nest membership of any member listed in `NestMembers` attribute. Instead, `Class::getNestMembers` returns the nest host and the members listed in the host's `NestMembers` attribute that are successfully resolved and determined to have the same nest host as this class. (This means it may return fewer members that listed in `NestMembers` attribute.) Existing code that expects `LinkageError` when there is a bad nest membership might be impacted.
                
4. The nestmate test in the JVM is changed to throw only `IllegalAccessError` when the nest membership is invalid. Some historical understanding is necessary:
- In Java 8, every access control failure was signaled with `IllegalAccessError` (IAE). Moreover, if a given access check failed with IAE once, then the same check would fail with IAE every time.
- In Java 11, the introduction of nest mates (JEP 181) meant that an access control failure could be signaled either with `IllegalAccessError` or, if nest membership was invalid, `LinkageError`. Still, if a given access check failed with a specific exception, then the same check would always fail with the same exception.
- In Java 15, the introduction of `Lookup::defineHiddenClass` implies that the nest host of the lookup class must be determined eagerly, when the hidden class is defined as a nestmate of the lookup class. Both `Lookup::defineHiddenClass` and `Class::getNestHost` both determine the nest host of a class in a more resilient manner than the JVM did in Java 11; namely, the API simply treats a class as self-hosted if its purported nest membership is invalid. For consistency with the API, the JVM no longer throws `LinkageError` when a class's nest membership is invalid, and instead treats the class as self-hosted. This means that the JVM only throws IAE from access control (because a self-hosted class will not permit any other class to access its private members). This is the behavior expected by the vast majority of user code.

5. JVM TI `GetClassSignature` returns a string that contains a ASCII dot (`.`)  for a hidden class.  JVM TI agents might need updating for hidden classes if they assume the returned string from `GetClassSignature` is a type descriptor conforming to JVMS 4.3.