In this tutorial, we're going to explore the motivation behind Java preview features, their difference compared to experimental features, and how to enable them with different tools.
2. Why Preview Features
As it's probably clear to everyone by now, Java feature releases are delivered every six months. This means less waiting time for new Java features, but at the same time, it means also less time to react to feedback about new features.
This is Java we're talking about here. It's used to develop a huge number of production systems. As a result, even a small malfunction in one implementation or a poor feature design could turn out to be very costly.
There must be a way to ensure new features are stable. More importantly, they have to suit the needs of the community. But how?
Thanks to JEP-12, “review language and VM features” can be included in the deliveries. This way, the community can check out new features in real-life scenarios – surely not in production, however.
Based on community feedback, a preview feature could be refined, possibly several times over multiple releases. Eventually, the feature may become permanent. But in some cases, the provided reviews could lead to withdrawing a preview feature entirely.
3. Preview Versus Experimental Features
Java preview features are completely specified and developed features that are going through evaluation. Therefore, they have just not reached the final state yet.
Because of their high quality, different JDK implementations must include all preview features planned within each Java delivery. However, a Java release still can't support preview features from earlier releases.
Preview features are essentially just a way to encourage the community to review and provide feedback. Moreover, not every Java feature must go through a preview stage in order to become final.
Here's what JEP-12 has to say about preview features:
A preview language or VM feature is a new feature whose design, specification, and implementation are all complete, but which would benefit from a period of broad exposure and evaluation before either achieving final and permanent status in the Java SE Platform or else being refined or removed.
On the other hand, experimental features are far from complete. Their artifacts are clearly separated from the JDK artifacts.
Experimental features are unstable and, as such, they impose a risk upon the language. Consequently, different JDK implementations may include different sets of experimental features.
4. Using Preview Features
Preview features are disabled by default. To enable them, we must use the enable-preview argument, which enables all preview features at once.
The Java compiler, as well as the JVM, must be of the same Java version that includes the preview feature we want to use.
Let's try to compile and run a piece of code that uses text blocks, a preview feature within JDK 13:
String query = """ SELECT 'Hello World' FROM DUAL; """; System.out.println(query);
Of course, we need to make sure we're using JDK 13 with our favorite IDE. We can, for instance, download the OpenJDK release 13 and add it to our IDE's Java runtime.
4.1. With Eclipse
At first, Eclipse will mark the code with red, as it won't compile. The error message will tell us to enable preview features in order to use text blocks.
We need to right-click on the project and select Properties from the pop-up menu. Next, we go to Java Compiler. Now, we can choose to enable preview features either for this specific project or for the entire workspace.
Next, we have to uncheck Use default compliance settings, and only then can we check Enable preview features for Java 13:
4.2. With IntelliJ IDEA
As we'd expect, the code won't compile in IntelliJ by default either, even with Java 13, and we'll get an error message similar to the one we saw in Eclipse.
We can enable preview features from Project Structure in the File menu. From Project, we need to select 13 (Preview) as the Project language level:
This should do it. However, if the error still persists, we have to manually add the compiler arguments to enable preview features. Assuming it's a Maven project, the compiler plugin in the pom.xml should contain:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>13</source> <target>13</target> <compilerArgs> --enable-preview </compilerArgs> </configuration> </plugin> </plugins> </build>
If required, we can enable preview features for other Maven plugins within their respective configurations in a similar way.
4.3. From Command Line
At compile time, the javac command needs two arguments — enable-preview and release:
javac --release 13 --enable-preview ClassUsingTextBlocks.java
Let's recall that a JDK release N doesn't support preview features of release N-1 or any previous releases. Therefore, we'll get an error if we try to execute the previous command with JDK 14.
Long story short, the release argument must set N to the JDK release version of the compiler (and JVM) being used in order to enable preview features.
The release argument is just an extra guard to ensure code using preview features won't be eagerly used in production.
At runtime, the java command only requires the enable-preview argument:
java --enable-preview ClassUsingTextBlocks
However, only code using the preview features of that specific JDK release would run.
In this article, we've introduced preview features in Java, why we have them, and how they differ from experimental features.
Then, using the text blocks preview feature in JDK 13, we explained step by step how to use preview features from Eclipse, IntelliJ, Maven, and the command line.