Improving compiler messages for preview API

Joe Darcy joe.darcy at
Wed Aug 7 18:52:22 UTC 2019

Hi Alex,

On 8/2/2019 5:07 PM, Alex Buckley wrote:
> Hi Joe,
> On 6/20/2019 10:18 AM, Joe Darcy wrote:> Time is late in JDK 13, but 
> for, say, JDK 14 it may be reasonable to add
>> a java.lang.Preview annotation type to mark preview API elements 
>> rather than relying on overloading the deprecation mechanism. Such an 
>> annotation type would be @Documented and applicable to the sort of 
>> declarations @Deprecated can be applied to.
> I think @Preview is the right way to go for JDK 14+. It would underpin 
> a number of scenarios where we wish to call developers' attention to 
> preview features:
> 1. In javadoc -- A casual reader of String::stripIndent's javadoc 
> should realize that this method is special: its association with a 
> preview feature (text blocks) means that it might change or go away in 
> the next release without going through a deprecate-and-wait cycle like 
> normal Java SE methods. An @Documented annotation such as @Preview 
> would let the standard doclet give special visual treatment to 
> types/fields/methods ("API elements") associated with preview features.
> 2. At compile time -- If you compile with --enable-preview, then any 
> source code reference to an API element associated with a preview 
> feature should generate a (non-suppressible) warning. This warning, 
> which would require JLS support, would be distinct from deprecation 
> warnings; we would then be in a position in JDK 14+ to drop the 
> terminally-deprecated-at-birth scheme adopted in JEP 12 as a stopgap.

To be precise on terminology, if compiling with --enable-preview, I 
think the warnings generated for using preview languages feature and 
associated API elements should be a little-w warnings. That is, messages 
from the compiler that still allows the compile to exist with a zero 
exit code. Operationally, such messages would be Diagnostic.Kind.NOTE 
rather than Diagnostic.Kind.{WARNING, MANDATORY_WARNING}.

The goal would be to allow a clean compile under "-Xlint:all -Werror" 
when preview features were being used. Not allowing "successful" compile 
of preview features would further complicate adding preview features to 
CI pipelines, etc.

> 3. At run time -- If you compile without --enable-preview, and the 
> source code refers to an API element associated with a preview 
> feature, then javac could give a (non-suppressible) warning and _mark 
> the class file as depending on preview features_. It is important to 
> handle this scenario firmly because the API element might be gone in a 
> later release. Annotating the type/method gives grounds for javac to 
> explain what's going on: "This method is marked @Preview; your class 
> file is now preview-feature dependent."

As I understand it, currently the call file target to use in javac is 
determined solely from the command line arguments at the start of the 
compile. It may be awkward to change this during the compile. (And would 
it change only for the for the types using the preview feature or fall 
all types in the compile?)

> The annotation type that you defined in the webrev 
> (j.l.a.PreviewFeature) looks good. However, I don't think the 
> `release` element is needed. The API in SE $N is what it is; API 
> elements associated with a preview feature are there because a JEP put 
> them there. The `release` element would always be the current JDK 
> release.

It isn't necessarily the case an API associated with a preview feature 
will have been introduced in the most recent JDK. For example, treating 
JEP 325: "Switch Expressions (Preview)" in 12 and JEP 354: "Switch 
Expressions (Preview)" in 13 as iterations of the same feature, the tree 
API has methods to support switch expression support from both JDK 12 
and 13:

SwitchExpressionTree introduced in 12, still in use in 13:

YieldTree introduced in 13:

This situation hasn't occurred yet in the Java SE APIs, but if the 
iterations of a feature are previewed over multiple releases, it 
certainly could.

The "release" element was modeled after the "since" element in 
java.lang.Deprecated. It isn't essential information, but I think it is 
useful to have it presented.


More information about the compiler-dev mailing list