JDK Toolchain discovery mechanism

Since version 3.2.0, the plugin provides a heuristic to discover installed JDK toolchains, by looking at known installation directories and at environment variables.

The list of discovered toolchains can be easily displayed using the command mvn org.apache.maven.plugins:maven-toolchains-plugin:3.2.0:display-discovered-jdk-toolchains. This will print something like:

[INFO] Discovered 10 JDK toolchains:
[INFO]   - /Users/gnodet/.sdkman/candidates/java/21.0.2-graalce
[INFO]     provides:
[INFO]       version: 21.0.2
[INFO]       runtime.name: OpenJDK Runtime Environment
[INFO]       runtime.version: 21.0.2+13-jvmci-23.1-b30
[INFO]       vendor: GraalVM Community
[INFO]       vendor.version: GraalVM CE 21.0.2+13.1
[INFO]       current: true
[INFO]       lts: true
[INFO]       env: JAVA_HOME,JAVA21_HOME
...

If you have installed JDKs using known installers and they are not found by the plugin, feel free to raise an issue.

The discovery mechanism provides information for each discovered JDK:

  • version: the JDK version
  • runtime.name: the name of the JDK runtime
  • runtime.version: the version of the JDK runtime
  • vendor: the vendor name
  • vendor.version: the vendor version
  • current: set to true if this is the running JDK
  • lts: set to true if JDK version is a long-term supported version
  • env: set to the comma separated list of JAVA{xyz}_HOME> matching environment variables

The select-jdk-toolchain goal finds a matching JDK. The config below allows using the current JDK, or any other discovered JDK >= 17. The current JDK can be kept for speed, but JDK 17 or higher will be used if the current JDK is older than 17:

<properties>
  <toolchain.jdk.version>[17,)</toolchain.jdk.version>
<properties>

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-toolchains-plugin</artifactId>
  <version>3.2.0</version>
  <executions>
    <execution>
      <goals>
        <goal>select-jdk-toolchain</goal>
      </goals>
    </execution>
  </executions>
</plugin>

If you use environment variables to configure your JDKs, you can use the following configuration to select the toolchain which is configured using the JAVA17_HOME environment variable.

<properties>
  <toolchain.jdk.version>JAVA17_HOME</toolchain.jdk.version>
<properties>

You can also do everything only at CLI level, without modifying your pom.xml

mvn toolchains:select-jdk-toolchain -Dtoolchain.jdk.version="[17,)" compile

Selection mechanism

Several properties can express requirements to match against discovered JDK toolchains:

  • version / toolchain.jdk.version: a version range such as [17,18) to match against the JDK version
  • runtimeName / toolchain.jdk.runtime.name
  • runtimeVersion / toolchain.jdk.runtime.version
  • vendor / toolchain.jdk.vendor
  • env / toolchain.jdk.env: the name of an environment variable that the JDK toolchain must match

The useJdk can be used to define whether the current JDK can be used if it matches the requirements.

Sorting

Multiple discovered JDK toolchains may satisfy the requirements. In such a case, you can express preferences for sorting the toolchains. This can be done using the comparator configuration which is a comma separated list of criteria amongst the following:

  • lts: prefer LTS toolchains
  • current: prefer the current JDK
  • env: prefer toolchains discovered from environment variables
  • version: prefer higher JDK versions
  • vendor: sort alphabetically by vendor name

The default value is lts,current,env,version,vendor.

toolchains.xml file

The generation of the toolchains.xml file is not necessary to use discovered JDK toolchains. The select-jdk-toolchain will select a toolchain amongst explicitly configured toolchains in toolchains.xml and discovered JDK toolchains. Discovered JDK toolchains are cached in ~/.m2/discovered-jdk-toolchains-cache.xml file by default, to speed up builds.

If you prefer, you can use the generate-jdk-toolchains-xml to generate a toolchains.xml. This can be used in conjunction with the discoverToolchains=false configuration to disable discovery and only use explicitly configured toolchains.