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

javac support for Preview APIs

    XMLWordPrintable

Details

    • CSR
    • Resolution: Approved
    • P3
    • 17
    • tools
    • None
    • behavioral
    • minimal
    • Hide
      - javac in JDK 16 is more precise about marking which class files depend on preview features than javac in JDK 15. If a program uses preview features (or classes declared to use preview features) in only one part of itself, then users who previously had to give `--enable-preview` to start the program (since _all_ its class files were marked) may find they can start the program without giving `--enable-preview`, only to experience errors due to loading marked class files at a later time, as the program's classes are loaded. However, since marked class files are never meant for distribution, there is no real compatibility risk -- the "users" in this paragraph are really developers who are trying out preview features in their own programs and would in all likelihood give `--enable-preview` to start those programs.

      - javac in JDK 16 emits a suppressible warning for indirect use of a preview language feature, that is, when code which does not itself use a preview language feature uses a type which was declared using a preview language feature. (This aligns with the suppressible warning when code uses a type which was declared as part of a [standalone, essential, or convenient] preview API.) The code most likely written by the same developer who created the type declared to use a preview language feature. The risk of this code failing to compile because of this suppressible warning is minimal. Moreover, any non-zero risk is outweighed by the educational aspect of the warning: since preview language features can be evolved, any type declared using a preview language feature can have its meaning changed, so any code which uses such a type should be notified.
      Show
      - javac in JDK 16 is more precise about marking which class files depend on preview features than javac in JDK 15. If a program uses preview features (or classes declared to use preview features) in only one part of itself, then users who previously had to give `--enable-preview` to start the program (since _all_ its class files were marked) may find they can start the program without giving `--enable-preview`, only to experience errors due to loading marked class files at a later time, as the program's classes are loaded. However, since marked class files are never meant for distribution, there is no real compatibility risk -- the "users" in this paragraph are really developers who are trying out preview features in their own programs and would in all likelihood give `--enable-preview` to start those programs. - javac in JDK 16 emits a suppressible warning for indirect use of a preview language feature, that is, when code which does not itself use a preview language feature uses a type which was declared using a preview language feature. (This aligns with the suppressible warning when code uses a type which was declared as part of a [standalone, essential, or convenient] preview API.) The code most likely written by the same developer who created the type declared to use a preview language feature. The risk of this code failing to compile because of this suppressible warning is minimal. Moreover, any non-zero risk is outweighed by the educational aspect of the warning: since preview language features can be evolved, any type declared using a preview language feature can have its meaning changed, so any code which uses such a type should be notified.
    • Java API, Language construct, Other
    • SE

    Description

      Summary

      JEP 12 "Preview Features" has been updated to define Preview APIs, and to clarify the use of classes which are declared using preview language features. The JDK's Java compiler, javac, needs to be updated to match these updates to JEP 12, and to adhere more precisely to JEP 12 overall.

      Problem

      javac needs to be updated to match the updated requirements of JEP 12.

      Solution

      Change javac as follows:

      1. Preview APIs are split into two broad groups: normal and reflective. Normal preview APIs are subdivided by JEP 12 into three kinds -- essential, convenient, standalone -- for expository purposes; however, javac is interested only in the fact that code uses a normal preview API versus a reflective preview API, and not in which kind of normal preview API. The critical point is that normal preview APIs can only be used with the --enable-preview flag, while reflective preview APIs may be used without the --enable-preview flag.

      2. Adhere to a long-standing JEP 12 requirement to provide a suppressible warning when code uses a class declared using a preview language feature. (Example. Consider the declaration record Point(...) {} which uses a preview language feature and must therefore be compiled with --enable-preview. The result is Point.class, a class file that can only be used with --enable-preview. Accordingly, to compile code that uses Point, such as Point p = new Point(...), it has always been necessary to run javac with --enable-preview. However, JEP 12 further intended that any use of a preview language feature should generate a warning: direct use (record ...) generates an non-suppressible warning, and indirect use (Point p = new Point(...)) generates a suppressible warning. The latter was unfortunately not generated in JDK 15.)

      3. Mark class files as depending on preview features (minor_version 65535) only if they need it. In JDK 15, all class files produced by javac when --enable-preview flag was provided were marked as depending on preview features -- even if the code in a class made no use of preview features. In JDK 16, only classes that use preview features will have their class files marked.

      Specification

      Where use of a preview feature is detected (or use of a class declared using a preview language feature), javac behaves as shown in the table below. "Suppression" means that @SuppressWarnings("preview") is applied in the source code at the point where the preview feature (or a class declared using a preview language feature) is used/invoked/overridden.


      Use of ...
      --enable-preview
      No Suppression
      --enable-preview
      Suppression
      No --enable-preview
      No Suppression
      No --enable-preview
      Suppression
      Preview language feature mandatory warning mandatory warning error error
      A class declared using a preview language feature mandatory warning no warning error error
      Normal preview API mandatory warning [1] no warning error [1] error [1]
      Reflective preview API mandatory warning no warning mandatory warning no warning

      [1] Referring to a normal preview API in the same module is allowed without a warning / error (--enable-preview / no --enable-preview, respectively) See "Special rules for declarations of preview APIs" in JEP 12.

      The table above describes behavior that has existed in JEP 12 since inception, and subsumes a more limited table that described behavior for "APIs associated with preview language features" in an earlier CSR (JDK-8231411). The formulation of the table above is as follows:

      • The rows "Preview language feature" and "A class declared using a preview language feature" describe longstanding behavior from JEP 12, prior to it dealing with APIs in any way.
      • The row "Normal preview API" corresponds to the "Essential" row in the earlier CSR.
      • The row "Reflective preview API" corresponds to the "Non-essential" row in the earlier CSR.

      The precise output of javac for a "mandatory warning" is unchanged from JDK 15:

      • With -Xlint:preview, a warning on each occurrence.
      • With -Xlint:-preview, a summary at the end of the compilation, stating preview features have been used.

      The default setting for the preview lint is unchanged from JDK 15:

      • -Xlint:preview when no --enable-preview is present.
      • -Xlint:-preview when --enable-preview is present.

      An explicit -Xlint setting overrides this default.

      javac marks a class file as depending on preview features (minor_version 65535) under the following conditions:

      • The corresponding source code uses a preview language feature, or a class declared using a preview language feature, or a normal preview API. (Use of a reflective preview API is exempt; see "Special rule for use of reflective preview APIs" in JEP 12.)
      • The corresponding source code is part of a preview API. (See "Special rules for declarations of preview APIs" in JEP 12.)
      • javac uses a preview VM feature in the generated class file.

      This is a change from JDK 15, where all class files are marked as depending on preview features when compiling with --enable-preview.

      Attachments

        1. JEP12.zip
          39 kB
        2. jep12-2020-12-07.md
          55 kB
        3. jep12-jls.txt
          4 kB

        Issue Links

          Activity

            People

              jlahoda Jan Lahoda
              jlahoda Jan Lahoda
              Alex Buckley
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: