JDK-8265090 : implement Sealed Classes as a standard feature in Java
  • Type: CSR
  • Component: core-libs
  • Sub-Component: java.lang
  • Priority: P3
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 17
  • Submitted: 2021-04-12
  • Updated: 2021-06-01
  • Resolved: 2021-05-13
Related Reports
CSR :  
Relates :  
Relates :  
Description
Summary
-------

Sealed Classes were originally proposed by JEP 360 in 2019 and was targeted to JDK 15 as a preview feature. Feedback on the feature was positive. Some changes were proposed including the enhancement of narrowing reference conversion to perform stricter checking of cast conversions with respect to sealed type hierarchies. Sealed Classes were proposed again by JEP 397 and targeted to JDK 16, again as a preview feature. Feedback suggests that the Sealed Classes feature is now ready to be made final and permanent as proposed by JEP 409.

Problem
-------

The preview status of Sealed Classes prevents usage in standard Java.

Solution
--------

Remove the preview status requirement from Sealed Classes related APIs.

Specification
-------------

This CSR is concerned only with removing the preview status from the API. The changes are listed below.

Note: apart from the changes to `java.lang.Class` related API a small change to the API of `com.sun.source.tree.ClassTree` is also included.

    diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java
          *
          * @jls 8.1 Class Declarations
          * @jls 9.1 Interface Declarations
    -     * @since 15
    +     * @since 17
          */
    -    @jdk.internal.javac.PreviewFeature(feature=jdk.internal.javac.PreviewFeature.Feature.SEALED_CLASSES, reflective=true)
         @CallerSensitive
         public Class<?>[] getPermittedSubclasses() { ... }

          * subclasses; {@link #getPermittedSubclasses()} returns a non-null but
          * possibly empty value for a sealed class or interface.
          *
    -     * @return {@code true} if and only if this {@code Class} object represents a sealed class or interface.
    +     * @return {@code true} if and only if this {@code Class} object represents
    +     * a sealed class or interface.
          *
          * @jls 8.1 Class Declarations
          * @jls 9.1 Interface Declarations
    -     * @since 15
    +     * @since 17
          */
    -    @jdk.internal.javac.PreviewFeature(feature=jdk.internal.javac.PreviewFeature.Feature.SEALED_CLASSES, reflective=true)
    -    @SuppressWarnings("preview")
         public boolean isSealed() { ... }

    diff --git a/src/jdk.compiler/share/classes/com/sun/source/tree/ClassTree.java b/src/jdk.compiler/share/classes/com/sun/source/tree/ClassTree.java
    @@ -93,10 +93,8 @@ public interface ClassTree extends StatementTree {
          *
          * @return the subclasses
          *
    -     * @since 15
    +     * @since 17
          */
    -    @jdk.internal.javac.PreviewFeature(feature=jdk.internal.javac.PreviewFeature.Feature.SEALED_CLASSES,
    -                                       reflective=true)
         default List<? extends Tree> getPermitsClause() { ... }
Comments
I only expect the PermittedSubclasses attribute to be supported by the JVM TI RedefineClasses and RetransformClasses (it is already fixed as noted above). Also, the attribute has to be supported by implementation of the JvmtiClassFileReconstituter (it is fixed as well). It should also indirectly impact the Instrumentation::redefineClasses���/redefineClasses��� and the JDI VirtualMachine::redefineClasses���. These methods should automatically return UOE if the JVM TI RetransformClasses/RedefineClasses return the error code JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED. Also, the specifications of these methods for a couple of latest JDK releases do not list all attributes that are not allowed to change but rather refer to the relevant spots in JVM TI spec. So, I think, everything is covered for the JEP 409.
18-05-2021

[~sspitsyn], please confirm no additional changes are needed in serviceability to support sealed classes, JVMTI, class file redefinition, etc. Moving to conditionally approve this CSR with the understanding that if any needed serviceability changes are identified, they will be done under a subsequent change if this change has already been integrated.
13-05-2021

[~vromero], looking over the code changes for the first preview of sealed classes, as javadoc is built on top of the javax.lang.model now, I suppose it doesn't need explicit additional API changes and the tree API changes are covered in this CSR. So, at this time, I don't see a need for an explicit CSR for the javadoc update; thanks.
13-05-2021

[~gbierman], looking at the the JVM TI API, it already seems to have some coverage of sealed classes as a preview feature: " The redefinition [of a class] must not change the NestHost, NestMembers, Record, or PermittedSubclasses attributes. " However, I think it would be prudent for the serviceability team to give another once-over to sealed class matters before the feature is finalized.
13-05-2021

This change nothing to the current discussion but Gavin said > Hidden classes can't be named, so can't be extended This is true currently but may be not be true in the future, if the current parametric VM spec is implemented
13-05-2021

[~darcy] I think that none of the changes in the javadoc code affect any public API, I don't think we need a CSR for them unless you suggest that we should have it for documentation reasons
13-05-2021

[~darcy] I double-checked with [~hseigel]: 1. The JVM doesn't care about ACC_ANNOTATION except requiring ACC_INTERFACE. 2. I looked at the JVMTI API's at https://docs.oracle.com/en/java/javase/16/docs/specs/jvmti.html#FunctionIndex and didn't see any needed changes. I think that covers all your points?
13-05-2021

[~darcy] I discussed your remaining questions with Dan. Here are our responses: > Should JVMS have any analogue of the annotation type���s cannot be sealed check? I'd tentatively say no. There are no JVMS checks based on ACC_ANNOTATION, other than requiring ACC_INTERFACE. The JVM doesn't care what you put in your annotation declaration. I'll run this one past [~hseigel] for his opinion. > Does the discussion of hidden classes need to be updated for sealed classes? I'm not seeing any interaction. Hidden classes can't be named, so can't be extended at all, and can't extend a sealed class. That seems fine, and the checks described in 5.3.5 make sense without any tweaks. > Are there any interactions between sealed classes and nest mates that should be called out in JVMS? We simulate resolution of the classes named in PermittedSubclasses, and so do access checking, but classes can only be public or package-access, so the check doesn't interact with nests. I can't think of any other interactions���they're orthogonal features. > Do any Java agent/JMV TI interfaces need to be updated for sealed classes? No idea I'm afraid. I'll forward this one to [~hseigel] in case he has an opinion. > Are any needed changes to the javadoc API going to be covered and receive CSR review under JDK-8265684? I think this one is for [~vromero].
13-05-2021

[~darcy] I attach the latest jls and jvms specs resulting from reviews by Alex, Dan and Harold. This covers your observation about there being a stale reference about records. (More generally, the specs had not been correctly rebased to reflect changes made in JDK 16. This has now been addressed.) Some other minor changes have been made.
12-05-2021

[~vromero] and [~gbierman], the "_D" draft has a stale reference: "JEP 395 proposes supporting Record classes in the Java programming language. A record class is implicitly final, so can implement a sealed interface." Please remove it and attach a new version of the document. Moving the CSR back to Provisional. A few addition questions and observations: Observation: type annotations are syntactically not allowed in permits clauses. Questions: Should JVMS have any analogue of the annotation type's cannot be sealed check? Does the discussion of hidden classes: https://docs.oracle.com/en/java/javase/16/docs/api/java.base/java/lang/invoke/MethodHandles.Lookup.html#defineHiddenClass(byte%5B%5D,boolean,java.lang.invoke.MethodHandles.Lookup.ClassOption...) need to be updated for sealed classes? Are there any interactions between sealed classes and nest mates that should be called out in JVMS? Do any Java agent/JMV TI interfaces need to be updated for sealed classes? Are any needed changes to the javadoc API going to be covered and receive CSR review under JDK-8265684?
10-05-2021

[~darcy] I have uploaded: jep409-0420_D_2021.zip after [~jfranck] reported offline that the specs were still referring to Sealed Classes as a preview feature. Thanks!
27-04-2021

[~darcy] I have uploaded: jep409-0414_C_2021.zip which is basically the same as jep409-0414_b_2021.zip but I added the .diff files for JVMS and JLS.
23-04-2021

I have uploaded jep409-0414_b_2021.zip which contains the JVMS and also a separate JLS change that is concerned with contextual keywords like sealed and non-sealed. Regarding the javadoc output yes, if a permitted type is not accessible then it is not included in the output
20-04-2021

Are there any non-obvious implications of how javadoc is generated for sealed types? For example, if one of the permitted type is not fully accessible, is the type elided in the output?
20-04-2021

Moving to Provisional, not Approved. Before the request is Finalized, please include the JVM spec changes as well. A diff of the semantics of this version of the sealed feature with previous versions would expedite the review.
20-04-2021

Updating scope to include language construct and JVM changes per discussions in JEP 397.
20-04-2021

[~darcy] I have uploaded the current JLS spec for sealed classes
20-04-2021

Moving to Provisional. If this issue is going to be used for the bulk sealed classes work, it should also include the JLS changes.
16-04-2021