DEV Community

Karl Heinz Marbaise
Karl Heinz Marbaise

Posted on

Using JDK21 Preview Features and/or incubator classes

Sometimes you want to play around with those new fancy features of JDK21 (or even newer JDK's) like preview features and maybe some classes from the incubator.

So how can you configure your Maven build to support such a play lesson? It's easier than you think. Let's start the configuration. My assumption is that you would like to play around with a preview features of JDK21 for example String Templates (JEP430). I just selected this JEP for demonstration. You can select whatever JEP in preview.

The first thing is to know that you have to activate the preview features via:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>
  <configuration>
    <enablePreview>true</enablePreview>
  </configuration>
</plugin>
Enter fullscreen mode Exit fullscreen mode

The configuration enablePreview exists since version 3.10.1 of the Maven Compiler Plugin. So in general I recommend to use the most recent versions of the plugins otherwise it might happen that some configuration options or alike might not exist at all or special things for newer JDK versions.

This should be done in general in the pluginManagement section of your pom.xml file.

So now you are able to use this new feature in your test code (you could use it in your production code as well if you prefer that):

package com.soebes.jdk21;

import org.junit.jupiter.api.Test;

import static java.lang.StringTemplate.STR;
import static org.assertj.core.api.Assertions.assertThat;

class TemplateTest {
  @Test
  void name() {
    String name = "Jon";
    String info = STR."My name is \{name}";
    assertThat(info).isEqualTo("My name is Jon");
  }

}
Enter fullscreen mode Exit fullscreen mode

Ok so far so good, but wait, before you can run this test you have to do a bit more. We need to change the configuration to run the test with the support of preview feature. This is required to give the JVM the option --enable-preview which is used during the execution of the tests. This has to be done like the following:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <configuration>
    <argLine>
      --enable-preview
    </argLine>
  </configuration>
</plugin>
Enter fullscreen mode Exit fullscreen mode

As I mentioned before, I strongly recommend to use the most recent versions of the plugins.

One important thing to mention. If you run those tests or the whole build you will get some WARNINGs like the following:

[INFO] --- compiler:3.11.0:testCompile (default-testCompile) @ jdk21 ---
[INFO] Changes detected - recompiling the module! :dependency
[INFO] Compiling 5 source files with javac [release 21] to target/test-classes
[WARNING] ../jdk21/src/test/java/com/soebes/jdk21/TemplateTest.java:[12,23] string templates are a preview feature and may be removed in a future release.
[WARNING] ../jdk21/src/test/java/com/soebes/jdk21/TemplateTest.java:[12,23] string templates are a preview feature and may be removed in a future release.
[WARNING] ../jdk21/src/test/java/com/soebes/jdk21/TemplateTest.java:[5,24] java.lang.StringTemplate is a preview API and may be removed in a future release.
[INFO] 
Enter fullscreen mode Exit fullscreen mode

Those WARNINGs would have been emitted during the production code compilation if you used such feature in the production already. This makes it clear that you are using such preview features.

And an extremely important hint:

Never deploy such code which uses preview features anywhere. Not in your company repository manger nor into central repository

The StringTemplate class is marked as a preview feature independent that it is the package java.lang:

@PreviewFeature(feature=PreviewFeature.Feature.STRING_TEMPLATES)
public interface StringTemplate {
  ...

}
Enter fullscreen mode Exit fullscreen mode

So another nice thing would be to use a class from the incubator like the Vector API? Ok. What do we need to do?
The first thing is to enhance our previous configuration with the --add-modules jdk.incubator.vector information
like the following:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>
  <configuration>
    <enablePreview>true</enablePreview>
    <compilerArgs>
      <arg>--add-modules</arg>
      <arg>jdk.incubator.vector</arg>
    </compilerArgs>
  </configuration>
</plugin>
Enter fullscreen mode Exit fullscreen mode

And of course you have to add the same to add to the maven-surefire-plugin configuration to activate the jdk.incubator.vector module in your tests as well. This means the configuration for maven-surefire-plugin should look like the following:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <configuration>
    <argLine>
      --enable-preview
      --add-modules jdk.incubator.vector
    </argLine>
  </configuration>
</plugin>
Enter fullscreen mode Exit fullscreen mode

This results in WARNING as before as the following:

..
[INFO] --- compiler:3.11.0:compile (default-compile) @ jdk21 ---
[INFO] Changes detected - recompiling the module! :source
[INFO] Compiling 2 source files with javac [release 21] to target/classes
[WARNING] using incubating module(s): jdk.incubator.vector
[INFO] 
[INFO] --- resources:3.3.1:testResources (default-testResources) @ jdk21 ---
[INFO] skip non existing resourceDirectory ../jdk21/src/test/resources
[INFO] skip non existing resourceDirectory ../jdk21/src/test/resources-filtered
[INFO] 
[INFO] --- compiler:3.11.0:testCompile (default-testCompile) @ jdk21 ---
[INFO] Changes detected - recompiling the module! :dependency
[INFO] Compiling 5 source files with javac [release 21] to target/test-classes
[WARNING] ../jdk21/src/test/java/com/soebes/jdk21/TemplateTest.java:[12,23] string templates are a preview feature and may be removed in a future release.
[WARNING] ../jdk21/src/test/java/com/soebes/jdk21/TemplateTest.java:[12,23] string templates are a preview feature and may be removed in a future release.
[WARNING] using incubating module(s): jdk.incubator.vector
[WARNING] ../jdk21/src/test/java/com/soebes/jdk21/TemplateTest.java:[5,24] java.lang.StringTemplate is a preview API and may be removed in a future release.
[INFO] 
[INFO] --- surefire:3.1.2:test (default-test) @ jdk21 ---
[INFO] Using auto detected provider org.apache.maven.surefire.junitplatform.JUnitPlatformProvider
[INFO] 
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
WARNING: Using incubator modules: jdk.incubator.vector
[INFO] Running com.soebes.jdk21.TemplateTest
.. 
Enter fullscreen mode Exit fullscreen mode

A small hint based on the usage of JDK21+. Starting with JDK21 the JEP-451 has been integrated into the JDK21 builds which means the usage of dynamic loaded agents for example the famous Mockito library results into WARNINGs as well which looks like this:

..
[INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.217 s -- in com.soebes.jdk21.SequencedCollectionTest
[INFO] Running com.soebes.jdk21.AFinalClassTest
OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended
WARNING: A Java agent has been loaded dynamically (/Users/khm/.m2/repository/net/bytebuddy/byte-buddy-agent/1.14.5/byte-buddy-agent-1.14.5.jar)
WARNING: If a serviceability tool is in use, please run with -XX:+EnableDynamicAgentLoading to hide this warning
WARNING: If a serviceability tool is not in use, please run with -Djdk.instrument.traceUsage for more information
WARNING: Dynamic loading of agents will be disallowed by default in a future release
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.472 s -- in com.soebes.jdk21.AFinalClassTest
[INFO] Running com.soebes.jdk21.incubator.VectorTest
..
Enter fullscreen mode Exit fullscreen mode

This makes it necessary to add the supplemental configuration -XX:+EnableDynamicAgentLoading to your maven-surefire-plugin configuration like this:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <configuration>
    <argLine>
      --enable-preview
      --add-modules jdk.incubator.vector
      -XX:+EnableDynamicAgentLoading
    </argLine>
  </configuration>
</plugin>
Enter fullscreen mode Exit fullscreen mode

A full working example which obviously requires JDK21 most recent EA build can be found here.

Happy coding.

Top comments (0)