elharo commented on code in PR #14:
URL: 
https://github.com/apache/maven-toolchains-plugin/pull/14#discussion_r1507960684


##########
src/site/apt/toolchains/discovery.apt.vm:
##########
@@ -0,0 +1,148 @@
+~~ Licensed to the Apache Software Foundation (ASF) under one
+~~ or more contributor license agreements.  See the NOTICE file
+~~ distributed with this work for additional information
+~~ regarding copyright ownership.  The ASF licenses this file
+~~ to you under the Apache License, Version 2.0 (the
+~~ "License"); you may not use this file except in compliance
+~~ with the License.  You may obtain a copy of the License at
+~~
+~~ http://www.apache.org/licenses/LICENSE-2.0
+~~
+~~ Unless required by applicable law or agreed to in writing,
+~~ software distributed under the License is distributed on an
+~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+~~ KIND, either express or implied.  See the License for the
+~~ specific language governing permissions and limitations
+~~ under the License.
+
+  ------
+  Discovery mechanism
+  ------
+  Guillaume Nodet
+  ------
+  2024-02-28
+  ------
+
+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:${project.version}: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 JDK using standard tools and they are not listed here, 
feel free
+  to {{{../issue-management.html}raise an issue}}.
+
+  The discovery mechanism provides a few information for each discovered JDK:

Review Comment:
   delete "a few"



##########
src/main/java/org/apache/maven/plugins/toolchain/jdk/SelectJdkToolchainMojo.java:
##########
@@ -0,0 +1,265 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.plugins.toolchain.jdk;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.stream.Stream;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.toolchain.MisconfiguredToolchainException;
+import org.apache.maven.toolchain.RequirementMatcherFactory;
+import org.apache.maven.toolchain.ToolchainFactory;
+import org.apache.maven.toolchain.ToolchainManagerPrivate;
+import org.apache.maven.toolchain.ToolchainPrivate;
+import org.apache.maven.toolchain.model.PersistedToolchains;
+import org.apache.maven.toolchain.model.ToolchainModel;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+
+import static org.apache.maven.plugins.toolchain.jdk.ToolchainDiscoverer.ENV;
+import static 
org.apache.maven.plugins.toolchain.jdk.ToolchainDiscoverer.RUNTIME_NAME;
+import static 
org.apache.maven.plugins.toolchain.jdk.ToolchainDiscoverer.RUNTIME_VERSION;
+import static 
org.apache.maven.plugins.toolchain.jdk.ToolchainDiscoverer.VENDOR;
+import static 
org.apache.maven.plugins.toolchain.jdk.ToolchainDiscoverer.VERSION;
+
+/**
+ * Discover JDK toolchains and select a matching one.
+ */
+@Mojo(name = "select-jdk-toolchain", defaultPhase = LifecyclePhase.VALIDATE)
+public class SelectJdkToolchainMojo extends AbstractMojo {
+
+    public static final String TOOLCHAIN_TYPE_JDK = "jdk";
+
+    /** Jdk usage mode */
+    public enum JdkMode {
+        /** always ignore the current JDK */
+        Never,
+        /** to not use a toolchain if the toolchains that would be selected is 
the current JDK */
+        IfSame,
+        /** favor the current JDK if it matches the requirements */
+        IfMatch
+    }
+
+    /**
+     * The version constraint for the JDK toolchain to select.
+     */
+    @Parameter(property = "toolchain.jdk.version")
+    private String version;
+
+    /**
+     * The runtime name constraint for the JDK toolchain to select.
+     */
+    @Parameter(property = "toolchain.jdk.runtime.name")
+    private String runtimeName;
+
+    /**
+     * The runtime version constraint for the JDK toolchain to select.
+     */
+    @Parameter(property = "toolchain.jdk.runtime.version")
+    private String runtimeVersion;
+
+    /**
+     * The vendor constraint for the JDK toolchain to select.
+     */
+    @Parameter(property = "toolchain.jdk.vendor")
+    private String vendor;
+
+    /**
+     * The env constraint for the JDK toolchain to select.
+     * To match the constraint, an environment variable with the given name 
must point to the JDK.
+     * For example, if you define {@code JAVA11_HOME=~/jdks/my-jdk-11.0.1}, 
you can specify
+     * {@code env=JAVA11_HOME} to match the given JDK.
+     */
+    @Parameter(property = "toolchain.jdk.env")
+    private String env;
+
+    /**
+     * The matching mode, either {@code IfMatch} (the default), {@code 
IfSame}, or {@code Never}.
+     * If {@code IfMatch} is used, a toolchain will not be selected if the 
running JDK does
+     * match the provided constraints. This is the default and provides better 
performances as it
+     * avoids forking a different process when it's not required. The {@code 
IfSame} avoids
+     * selecting a toolchain if the toolchain selected is exactly the same as 
the running JDK.
+     * THe {@code Never} option will always select the toolchain.
+     */
+    @Parameter(property = "toolchain.jdk.mode", defaultValue = "IfMatch")
+    private JdkMode useJdk = JdkMode.IfMatch;
+
+    /**
+     * Automatically discover JDK toolchains using the built-in heuristic.
+     * The default value is {@code true}.
+     */
+    @Parameter(property = "toolchain.jdk.discover", defaultValue = "true")
+    private boolean discoverToolchains = true;
+
+    /**
+     * Comparator used to sort JDK toolchains for selection.
+     * This property is a comma separated list of values which may contains:
+     * <ul>
+     * <li>{@code lts}: prefer JDK with LTS version</li>
+     * <li>{@code current}: prefer the current JDK</li>
+     * <li>{@code env}: prefer JDKs defined using {@code JAVA\{xx\}_HOME} 
environment variables</li>
+     * <li>{@code version}: prefer JDK with higher versions</li>
+     * <li>{@code vendor}: order JDK by vendor name (usually as a last 
comparator to ensure a stable order)</li>
+     * </ul>
+     */
+    @Parameter(property = "toolchain.jdk.comparator", defaultValue = 
"lts,current,env,version,vendor")
+    private String comparator;
+
+    /**
+     * Toolchain manager
+     */
+    @Inject
+    private ToolchainManagerPrivate toolchainManager;
+
+    /**
+     * Toolchain factory
+     */
+    @Inject
+    @Named(TOOLCHAIN_TYPE_JDK)
+    ToolchainFactory factory;
+
+    /**
+     * The current build session instance. This is used for toolchain manager 
API calls.
+     */
+    @Inject
+    private MavenSession session;
+
+    /**
+     * Toolchain discoverer
+     */
+    @Inject
+    ToolchainDiscoverer discoverer;
+
+    @Override
+    public void execute() throws MojoFailureException {
+        try {
+            doExecute();
+        } catch (MisconfiguredToolchainException e) {
+            throw new MojoFailureException("Unable to select toolchain: " + e, 
e);
+        }
+    }
+
+    private void doExecute() throws MisconfiguredToolchainException, 
MojoFailureException {
+        if (version == null && runtimeName == null && runtimeVersion == null 
&& vendor == null && env == null) {
+            return;
+        }
+
+        Map<String, String> requirements = new HashMap<>();
+        Optional.ofNullable(version).ifPresent(v -> requirements.put(VERSION, 
v));
+        Optional.ofNullable(runtimeName).ifPresent(v -> 
requirements.put(RUNTIME_NAME, v));
+        Optional.ofNullable(runtimeVersion).ifPresent(v -> 
requirements.put(RUNTIME_VERSION, v));
+        Optional.ofNullable(vendor).ifPresent(v -> requirements.put(VENDOR, 
v));
+        Optional.ofNullable(env).ifPresent(v -> requirements.put(ENV, v));
+
+        ToolchainModel currentJdkToolchainModel =
+                discoverer.getCurrentJdkToolchain().orElse(null);
+        ToolchainPrivate currentJdkToolchain =
+                currentJdkToolchainModel != null ? 
factory.createToolchain(currentJdkToolchainModel) : null;
+
+        if (useJdk == JdkMode.IfMatch && currentJdkToolchain != null && 
matches(currentJdkToolchain, requirements)) {
+            getLog().info("Not using an external toolchain as the current JDK 
matches the requirements.");
+            return;
+        }
+
+        ToolchainPrivate toolchain = 
Stream.of(toolchainManager.getToolchainsForType(TOOLCHAIN_TYPE_JDK, session))
+                .filter(tc -> matches(tc, requirements))
+                .findFirst()
+                .orElse(null);
+        if (toolchain != null) {
+            getLog().info("Found matching JDK toolchain: " + toolchain);
+        }
+
+        if (toolchain == null && discoverToolchains) {
+            getLog().debug("No matching toolchains configured, trying to 
discover JDK toolchains");
+            PersistedToolchains persistedToolchains = 
discoverer.discoverToolchains(comparator);
+            getLog().info("Discovered " + 
persistedToolchains.getToolchains().size() + " JDK toolchains");

Review Comment:
   this should probably be debug as well. 



##########
src/site/apt/toolchains/discovery.apt.vm:
##########
@@ -0,0 +1,148 @@
+~~ Licensed to the Apache Software Foundation (ASF) under one
+~~ or more contributor license agreements.  See the NOTICE file
+~~ distributed with this work for additional information
+~~ regarding copyright ownership.  The ASF licenses this file
+~~ to you under the Apache License, Version 2.0 (the
+~~ "License"); you may not use this file except in compliance
+~~ with the License.  You may obtain a copy of the License at
+~~
+~~ http://www.apache.org/licenses/LICENSE-2.0
+~~
+~~ Unless required by applicable law or agreed to in writing,
+~~ software distributed under the License is distributed on an
+~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+~~ KIND, either express or implied.  See the License for the
+~~ specific language governing permissions and limitations
+~~ under the License.
+
+  ------
+  Discovery mechanism
+  ------
+  Guillaume Nodet
+  ------
+  2024-02-28
+  ------
+
+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:${project.version}: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 JDK using standard tools and they are not listed here, 
feel free
+  to {{{../issue-management.html}raise an issue}}.
+
+  The discovery mechanism provides a few 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 discovering and selecting a matching JDK.
+  The config below allows using the current JDK, or any other discovered JDK 
>= 17.
+  The benefit is that the current JDK can be kept for speed, but ensuring the 
usage of any JDK 17 or higher if
+  the current jdk is below the requirements.
+
++---+
+<properties>
+  <toolchain.jdk.version>[17,)</toolchain.jdk.version>
+<properties>
+
+<plugin>
+  <groupId>org.apache.maven.plugins</groupId>
+  <artifactId>maven-toolchains-plugin</artifactId>
+  <version>${project.version}</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>
++---+
+
+* Selection mechanism
+
+  Several properties can be used to express requirements to match against 
discovered JDK toolchains:

Review Comment:
   delete "be used to"



##########
src/site/apt/toolchains/discovery.apt.vm:
##########
@@ -0,0 +1,148 @@
+~~ Licensed to the Apache Software Foundation (ASF) under one
+~~ or more contributor license agreements.  See the NOTICE file
+~~ distributed with this work for additional information
+~~ regarding copyright ownership.  The ASF licenses this file
+~~ to you under the Apache License, Version 2.0 (the
+~~ "License"); you may not use this file except in compliance
+~~ with the License.  You may obtain a copy of the License at
+~~
+~~ http://www.apache.org/licenses/LICENSE-2.0
+~~
+~~ Unless required by applicable law or agreed to in writing,
+~~ software distributed under the License is distributed on an
+~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+~~ KIND, either express or implied.  See the License for the
+~~ specific language governing permissions and limitations
+~~ under the License.
+
+  ------
+  Discovery mechanism
+  ------
+  Guillaume Nodet
+  ------
+  2024-02-28
+  ------
+
+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:${project.version}: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 JDK using standard tools and they are not listed here, 
feel free
+  to {{{../issue-management.html}raise an issue}}.
+
+  The discovery mechanism provides a few 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 discovering and selecting a matching JDK.
+  The config below allows using the current JDK, or any other discovered JDK 
>= 17.
+  The benefit is that the current JDK can be kept for speed, but ensuring the 
usage of any JDK 17 or higher if
+  the current jdk is below the requirements.
+
++---+
+<properties>
+  <toolchain.jdk.version>[17,)</toolchain.jdk.version>
+<properties>
+
+<plugin>
+  <groupId>org.apache.maven.plugins</groupId>
+  <artifactId>maven-toolchains-plugin</artifactId>
+  <version>${project.version}</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>
++---+
+
+* Selection mechanism
+
+  Several properties can be used to 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 match the above requirements.  In 
such a case, you may want to express
+  preferences to use to sort the toolchains.  This can be done using the 
<<<comparator>>> configuration which is a
+  comma separated list of criterions 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 toolchains.
+  The <<<select-jdk-toolchain>>> will select a toolchain amongst explicitly 
configured toolchains and discovered
+  toolchains. The information for discovered toolchains are cached in 
<<<~/.m2/discovered-toolchains-cache.xml>>> file
+  by default, to speed up things.
+
+  If you prefer, you can use the <<<generate-jdk-toolchains-xml>>> to generate 
a toolchain XML.  This can be used in
+  conjunction to the <<<discoverToolchains=false>>> configuration to disable 
the discovery and only use explicitly

Review Comment:
   conjunction to --> conjucntion with
   the discovery --> discovery



##########
src/site/apt/toolchains/discovery.apt.vm:
##########
@@ -0,0 +1,148 @@
+~~ Licensed to the Apache Software Foundation (ASF) under one
+~~ or more contributor license agreements.  See the NOTICE file
+~~ distributed with this work for additional information
+~~ regarding copyright ownership.  The ASF licenses this file
+~~ to you under the Apache License, Version 2.0 (the
+~~ "License"); you may not use this file except in compliance
+~~ with the License.  You may obtain a copy of the License at
+~~
+~~ http://www.apache.org/licenses/LICENSE-2.0
+~~
+~~ Unless required by applicable law or agreed to in writing,
+~~ software distributed under the License is distributed on an
+~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+~~ KIND, either express or implied.  See the License for the
+~~ specific language governing permissions and limitations
+~~ under the License.
+
+  ------
+  Discovery mechanism
+  ------
+  Guillaume Nodet
+  ------
+  2024-02-28
+  ------
+
+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:${project.version}: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 JDK using standard tools and they are not listed here, 
feel free
+  to {{{../issue-management.html}raise an issue}}.
+
+  The discovery mechanism provides a few 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 discovering and selecting a matching JDK.
+  The config below allows using the current JDK, or any other discovered JDK 
>= 17.
+  The benefit is that the current JDK can be kept for speed, but ensuring the 
usage of any JDK 17 or higher if
+  the current jdk is below the requirements.
+
++---+
+<properties>
+  <toolchain.jdk.version>[17,)</toolchain.jdk.version>
+<properties>
+
+<plugin>
+  <groupId>org.apache.maven.plugins</groupId>
+  <artifactId>maven-toolchains-plugin</artifactId>
+  <version>${project.version}</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>
++---+
+
+* Selection mechanism
+
+  Several properties can be used to 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 match the above requirements.  In 
such a case, you may want to express
+  preferences to use to sort the toolchains.  This can be done using the 
<<<comparator>>> configuration which is a
+  comma separated list of criterions amongst the following:

Review Comment:
   criterions --> criteria



##########
src/site/apt/toolchains/discovery.apt.vm:
##########
@@ -0,0 +1,148 @@
+~~ Licensed to the Apache Software Foundation (ASF) under one
+~~ or more contributor license agreements.  See the NOTICE file
+~~ distributed with this work for additional information
+~~ regarding copyright ownership.  The ASF licenses this file
+~~ to you under the Apache License, Version 2.0 (the
+~~ "License"); you may not use this file except in compliance
+~~ with the License.  You may obtain a copy of the License at
+~~
+~~ http://www.apache.org/licenses/LICENSE-2.0
+~~
+~~ Unless required by applicable law or agreed to in writing,
+~~ software distributed under the License is distributed on an
+~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+~~ KIND, either express or implied.  See the License for the
+~~ specific language governing permissions and limitations
+~~ under the License.
+
+  ------
+  Discovery mechanism
+  ------
+  Guillaume Nodet
+  ------
+  2024-02-28
+  ------
+
+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:${project.version}: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 JDK using standard tools and they are not listed here, 
feel free
+  to {{{../issue-management.html}raise an issue}}.
+
+  The discovery mechanism provides a few 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 discovering and selecting a matching JDK.
+  The config below allows using the current JDK, or any other discovered JDK 
>= 17.
+  The benefit is that the current JDK can be kept for speed, but ensuring the 
usage of any JDK 17 or higher if

Review Comment:
   The current JDK can be kept for speed, but JDK 17 or higher will be used if 
the current JDK is older than 17.



##########
src/main/java/org/apache/maven/plugins/toolchain/jdk/SelectJdkToolchainMojo.java:
##########
@@ -0,0 +1,265 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.plugins.toolchain.jdk;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.stream.Stream;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.toolchain.MisconfiguredToolchainException;
+import org.apache.maven.toolchain.RequirementMatcherFactory;
+import org.apache.maven.toolchain.ToolchainFactory;
+import org.apache.maven.toolchain.ToolchainManagerPrivate;
+import org.apache.maven.toolchain.ToolchainPrivate;
+import org.apache.maven.toolchain.model.PersistedToolchains;
+import org.apache.maven.toolchain.model.ToolchainModel;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+
+import static org.apache.maven.plugins.toolchain.jdk.ToolchainDiscoverer.ENV;
+import static 
org.apache.maven.plugins.toolchain.jdk.ToolchainDiscoverer.RUNTIME_NAME;
+import static 
org.apache.maven.plugins.toolchain.jdk.ToolchainDiscoverer.RUNTIME_VERSION;
+import static 
org.apache.maven.plugins.toolchain.jdk.ToolchainDiscoverer.VENDOR;
+import static 
org.apache.maven.plugins.toolchain.jdk.ToolchainDiscoverer.VERSION;
+
+/**
+ * Discover JDK toolchains and select a matching one.
+ */
+@Mojo(name = "select-jdk-toolchain", defaultPhase = LifecyclePhase.VALIDATE)
+public class SelectJdkToolchainMojo extends AbstractMojo {
+
+    public static final String TOOLCHAIN_TYPE_JDK = "jdk";
+
+    /** Jdk usage mode */
+    public enum JdkMode {
+        /** always ignore the current JDK */
+        Never,
+        /** to not use a toolchain if the toolchains that would be selected is 
the current JDK */
+        IfSame,
+        /** favor the current JDK if it matches the requirements */
+        IfMatch
+    }
+
+    /**
+     * The version constraint for the JDK toolchain to select.
+     */
+    @Parameter(property = "toolchain.jdk.version")
+    private String version;
+
+    /**
+     * The runtime name constraint for the JDK toolchain to select.
+     */
+    @Parameter(property = "toolchain.jdk.runtime.name")
+    private String runtimeName;
+
+    /**
+     * The runtime version constraint for the JDK toolchain to select.
+     */
+    @Parameter(property = "toolchain.jdk.runtime.version")
+    private String runtimeVersion;
+
+    /**
+     * The vendor constraint for the JDK toolchain to select.
+     */
+    @Parameter(property = "toolchain.jdk.vendor")
+    private String vendor;
+
+    /**
+     * The env constraint for the JDK toolchain to select.
+     * To match the constraint, an environment variable with the given name 
must point to the JDK.
+     * For example, if you define {@code JAVA11_HOME=~/jdks/my-jdk-11.0.1}, 
you can specify
+     * {@code env=JAVA11_HOME} to match the given JDK.
+     */
+    @Parameter(property = "toolchain.jdk.env")
+    private String env;
+
+    /**
+     * The matching mode, either {@code IfMatch} (the default), {@code 
IfSame}, or {@code Never}.
+     * If {@code IfMatch} is used, a toolchain will not be selected if the 
running JDK does
+     * match the provided constraints. This is the default and provides better 
performances as it
+     * avoids forking a different process when it's not required. The {@code 
IfSame} avoids
+     * selecting a toolchain if the toolchain selected is exactly the same as 
the running JDK.
+     * THe {@code Never} option will always select the toolchain.
+     */
+    @Parameter(property = "toolchain.jdk.mode", defaultValue = "IfMatch")
+    private JdkMode useJdk = JdkMode.IfMatch;
+
+    /**
+     * Automatically discover JDK toolchains using the built-in heuristic.
+     * The default value is {@code true}.
+     */
+    @Parameter(property = "toolchain.jdk.discover", defaultValue = "true")
+    private boolean discoverToolchains = true;
+
+    /**
+     * Comparator used to sort JDK toolchains for selection.
+     * This property is a comma separated list of values which may contains:
+     * <ul>
+     * <li>{@code lts}: prefer JDK with LTS version</li>
+     * <li>{@code current}: prefer the current JDK</li>
+     * <li>{@code env}: prefer JDKs defined using {@code JAVA\{xx\}_HOME} 
environment variables</li>
+     * <li>{@code version}: prefer JDK with higher versions</li>
+     * <li>{@code vendor}: order JDK by vendor name (usually as a last 
comparator to ensure a stable order)</li>
+     * </ul>
+     */
+    @Parameter(property = "toolchain.jdk.comparator", defaultValue = 
"lts,current,env,version,vendor")
+    private String comparator;
+
+    /**
+     * Toolchain manager
+     */
+    @Inject
+    private ToolchainManagerPrivate toolchainManager;
+
+    /**
+     * Toolchain factory
+     */
+    @Inject
+    @Named(TOOLCHAIN_TYPE_JDK)
+    ToolchainFactory factory;
+
+    /**
+     * The current build session instance. This is used for toolchain manager 
API calls.
+     */
+    @Inject
+    private MavenSession session;
+
+    /**
+     * Toolchain discoverer
+     */
+    @Inject
+    ToolchainDiscoverer discoverer;
+
+    @Override
+    public void execute() throws MojoFailureException {
+        try {
+            doExecute();
+        } catch (MisconfiguredToolchainException e) {
+            throw new MojoFailureException("Unable to select toolchain: " + e, 
e);
+        }
+    }
+
+    private void doExecute() throws MisconfiguredToolchainException, 
MojoFailureException {
+        if (version == null && runtimeName == null && runtimeVersion == null 
&& vendor == null && env == null) {
+            return;
+        }
+
+        Map<String, String> requirements = new HashMap<>();
+        Optional.ofNullable(version).ifPresent(v -> requirements.put(VERSION, 
v));
+        Optional.ofNullable(runtimeName).ifPresent(v -> 
requirements.put(RUNTIME_NAME, v));
+        Optional.ofNullable(runtimeVersion).ifPresent(v -> 
requirements.put(RUNTIME_VERSION, v));
+        Optional.ofNullable(vendor).ifPresent(v -> requirements.put(VENDOR, 
v));
+        Optional.ofNullable(env).ifPresent(v -> requirements.put(ENV, v));
+
+        ToolchainModel currentJdkToolchainModel =
+                discoverer.getCurrentJdkToolchain().orElse(null);
+        ToolchainPrivate currentJdkToolchain =
+                currentJdkToolchainModel != null ? 
factory.createToolchain(currentJdkToolchainModel) : null;
+
+        if (useJdk == JdkMode.IfMatch && currentJdkToolchain != null && 
matches(currentJdkToolchain, requirements)) {
+            getLog().info("Not using an external toolchain as the current JDK 
matches the requirements.");
+            return;
+        }
+
+        ToolchainPrivate toolchain = 
Stream.of(toolchainManager.getToolchainsForType(TOOLCHAIN_TYPE_JDK, session))
+                .filter(tc -> matches(tc, requirements))
+                .findFirst()
+                .orElse(null);
+        if (toolchain != null) {
+            getLog().info("Found matching JDK toolchain: " + toolchain);
+        }
+
+        if (toolchain == null && discoverToolchains) {
+            getLog().debug("No matching toolchains configured, trying to 
discover JDK toolchains");
+            PersistedToolchains persistedToolchains = 
discoverer.discoverToolchains(comparator);
+            getLog().info("Discovered " + 
persistedToolchains.getToolchains().size() + " JDK toolchains");
+
+            for (ToolchainModel tcm : persistedToolchains.getToolchains()) {
+                ToolchainPrivate tc = factory.createToolchain(tcm);
+                if (tc != null && matches(tc, requirements)) {
+                    toolchain = tc;
+                    getLog().debug("Discovered matching JDK toolchain: " + 
toolchain);
+                    break;
+                }
+            }
+        }
+
+        if (toolchain == null) {
+            throw new MojoFailureException(
+                    "Cannot find matching toolchain definitions for the 
following toolchain types:" + requirements
+                            + System.lineSeparator()
+                            + "Please make sure you define the required 
toolchains in your ~/.m2/toolchains.xml file.");

Review Comment:
   "Please make sure you define" --> "Define"
   
   
https://learn.microsoft.com/en-us/previous-versions/windows/desktop/bb226825(v=vs.85)



##########
src/main/java/org/apache/maven/plugins/toolchain/jdk/SelectJdkToolchainMojo.java:
##########
@@ -0,0 +1,265 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.plugins.toolchain.jdk;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.stream.Stream;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.toolchain.MisconfiguredToolchainException;
+import org.apache.maven.toolchain.RequirementMatcherFactory;
+import org.apache.maven.toolchain.ToolchainFactory;
+import org.apache.maven.toolchain.ToolchainManagerPrivate;
+import org.apache.maven.toolchain.ToolchainPrivate;
+import org.apache.maven.toolchain.model.PersistedToolchains;
+import org.apache.maven.toolchain.model.ToolchainModel;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+
+import static org.apache.maven.plugins.toolchain.jdk.ToolchainDiscoverer.ENV;
+import static 
org.apache.maven.plugins.toolchain.jdk.ToolchainDiscoverer.RUNTIME_NAME;
+import static 
org.apache.maven.plugins.toolchain.jdk.ToolchainDiscoverer.RUNTIME_VERSION;
+import static 
org.apache.maven.plugins.toolchain.jdk.ToolchainDiscoverer.VENDOR;
+import static 
org.apache.maven.plugins.toolchain.jdk.ToolchainDiscoverer.VERSION;
+
+/**
+ * Discover JDK toolchains and select a matching one.
+ */
+@Mojo(name = "select-jdk-toolchain", defaultPhase = LifecyclePhase.VALIDATE)
+public class SelectJdkToolchainMojo extends AbstractMojo {
+
+    public static final String TOOLCHAIN_TYPE_JDK = "jdk";
+
+    /** Jdk usage mode */
+    public enum JdkMode {
+        /** always ignore the current JDK */
+        Never,
+        /** to not use a toolchain if the toolchains that would be selected is 
the current JDK */
+        IfSame,
+        /** favor the current JDK if it matches the requirements */
+        IfMatch
+    }
+
+    /**
+     * The version constraint for the JDK toolchain to select.
+     */
+    @Parameter(property = "toolchain.jdk.version")
+    private String version;
+
+    /**
+     * The runtime name constraint for the JDK toolchain to select.
+     */
+    @Parameter(property = "toolchain.jdk.runtime.name")
+    private String runtimeName;
+
+    /**
+     * The runtime version constraint for the JDK toolchain to select.
+     */
+    @Parameter(property = "toolchain.jdk.runtime.version")
+    private String runtimeVersion;
+
+    /**
+     * The vendor constraint for the JDK toolchain to select.
+     */
+    @Parameter(property = "toolchain.jdk.vendor")
+    private String vendor;
+
+    /**
+     * The env constraint for the JDK toolchain to select.
+     * To match the constraint, an environment variable with the given name 
must point to the JDK.
+     * For example, if you define {@code JAVA11_HOME=~/jdks/my-jdk-11.0.1}, 
you can specify
+     * {@code env=JAVA11_HOME} to match the given JDK.
+     */
+    @Parameter(property = "toolchain.jdk.env")
+    private String env;
+
+    /**
+     * The matching mode, either {@code IfMatch} (the default), {@code 
IfSame}, or {@code Never}.
+     * If {@code IfMatch} is used, a toolchain will not be selected if the 
running JDK does
+     * match the provided constraints. This is the default and provides better 
performances as it
+     * avoids forking a different process when it's not required. The {@code 
IfSame} avoids
+     * selecting a toolchain if the toolchain selected is exactly the same as 
the running JDK.
+     * THe {@code Never} option will always select the toolchain.
+     */
+    @Parameter(property = "toolchain.jdk.mode", defaultValue = "IfMatch")
+    private JdkMode useJdk = JdkMode.IfMatch;
+
+    /**
+     * Automatically discover JDK toolchains using the built-in heuristic.
+     * The default value is {@code true}.
+     */
+    @Parameter(property = "toolchain.jdk.discover", defaultValue = "true")
+    private boolean discoverToolchains = true;
+
+    /**
+     * Comparator used to sort JDK toolchains for selection.
+     * This property is a comma separated list of values which may contains:
+     * <ul>
+     * <li>{@code lts}: prefer JDK with LTS version</li>
+     * <li>{@code current}: prefer the current JDK</li>
+     * <li>{@code env}: prefer JDKs defined using {@code JAVA\{xx\}_HOME} 
environment variables</li>
+     * <li>{@code version}: prefer JDK with higher versions</li>
+     * <li>{@code vendor}: order JDK by vendor name (usually as a last 
comparator to ensure a stable order)</li>
+     * </ul>
+     */
+    @Parameter(property = "toolchain.jdk.comparator", defaultValue = 
"lts,current,env,version,vendor")
+    private String comparator;
+
+    /**
+     * Toolchain manager
+     */
+    @Inject
+    private ToolchainManagerPrivate toolchainManager;
+
+    /**
+     * Toolchain factory
+     */
+    @Inject
+    @Named(TOOLCHAIN_TYPE_JDK)
+    ToolchainFactory factory;
+
+    /**
+     * The current build session instance. This is used for toolchain manager 
API calls.
+     */
+    @Inject
+    private MavenSession session;
+
+    /**
+     * Toolchain discoverer
+     */
+    @Inject
+    ToolchainDiscoverer discoverer;
+
+    @Override
+    public void execute() throws MojoFailureException {
+        try {
+            doExecute();
+        } catch (MisconfiguredToolchainException e) {
+            throw new MojoFailureException("Unable to select toolchain: " + e, 
e);
+        }
+    }
+
+    private void doExecute() throws MisconfiguredToolchainException, 
MojoFailureException {
+        if (version == null && runtimeName == null && runtimeVersion == null 
&& vendor == null && env == null) {
+            return;
+        }
+
+        Map<String, String> requirements = new HashMap<>();
+        Optional.ofNullable(version).ifPresent(v -> requirements.put(VERSION, 
v));
+        Optional.ofNullable(runtimeName).ifPresent(v -> 
requirements.put(RUNTIME_NAME, v));
+        Optional.ofNullable(runtimeVersion).ifPresent(v -> 
requirements.put(RUNTIME_VERSION, v));
+        Optional.ofNullable(vendor).ifPresent(v -> requirements.put(VENDOR, 
v));
+        Optional.ofNullable(env).ifPresent(v -> requirements.put(ENV, v));
+
+        ToolchainModel currentJdkToolchainModel =
+                discoverer.getCurrentJdkToolchain().orElse(null);
+        ToolchainPrivate currentJdkToolchain =
+                currentJdkToolchainModel != null ? 
factory.createToolchain(currentJdkToolchainModel) : null;
+
+        if (useJdk == JdkMode.IfMatch && currentJdkToolchain != null && 
matches(currentJdkToolchain, requirements)) {
+            getLog().info("Not using an external toolchain as the current JDK 
matches the requirements.");
+            return;
+        }
+
+        ToolchainPrivate toolchain = 
Stream.of(toolchainManager.getToolchainsForType(TOOLCHAIN_TYPE_JDK, session))
+                .filter(tc -> matches(tc, requirements))
+                .findFirst()
+                .orElse(null);
+        if (toolchain != null) {
+            getLog().info("Found matching JDK toolchain: " + toolchain);
+        }
+
+        if (toolchain == null && discoverToolchains) {
+            getLog().debug("No matching toolchains configured, trying to 
discover JDK toolchains");
+            PersistedToolchains persistedToolchains = 
discoverer.discoverToolchains(comparator);
+            getLog().info("Discovered " + 
persistedToolchains.getToolchains().size() + " JDK toolchains");
+
+            for (ToolchainModel tcm : persistedToolchains.getToolchains()) {
+                ToolchainPrivate tc = factory.createToolchain(tcm);
+                if (tc != null && matches(tc, requirements)) {
+                    toolchain = tc;
+                    getLog().debug("Discovered matching JDK toolchain: " + 
toolchain);
+                    break;
+                }
+            }
+        }
+
+        if (toolchain == null) {
+            throw new MojoFailureException(
+                    "Cannot find matching toolchain definitions for the 
following toolchain types:" + requirements
+                            + System.lineSeparator()
+                            + "Please make sure you define the required 
toolchains in your ~/.m2/toolchains.xml file.");
+        }
+
+        if (useJdk == JdkMode.IfSame
+                && currentJdkToolchain != null
+                && Objects.equals(getJdkHome(currentJdkToolchain), 
getJdkHome(toolchain))) {
+            getLog().info("Not using an external toolchain as the current JDK 
has been selected.");
+            return;
+        }
+
+        toolchainManager.storeToolchainToBuildContext(toolchain, session);
+        getLog().info("Found matching JDK toolchain: " + toolchain);

Review Comment:
   debug



##########
src/site/apt/toolchains/discovery.apt.vm:
##########
@@ -0,0 +1,148 @@
+~~ Licensed to the Apache Software Foundation (ASF) under one
+~~ or more contributor license agreements.  See the NOTICE file
+~~ distributed with this work for additional information
+~~ regarding copyright ownership.  The ASF licenses this file
+~~ to you under the Apache License, Version 2.0 (the
+~~ "License"); you may not use this file except in compliance
+~~ with the License.  You may obtain a copy of the License at
+~~
+~~ http://www.apache.org/licenses/LICENSE-2.0
+~~
+~~ Unless required by applicable law or agreed to in writing,
+~~ software distributed under the License is distributed on an
+~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+~~ KIND, either express or implied.  See the License for the
+~~ specific language governing permissions and limitations
+~~ under the License.
+
+  ------
+  Discovery mechanism
+  ------
+  Guillaume Nodet
+  ------
+  2024-02-28
+  ------
+
+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:${project.version}: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 JDK using standard tools and they are not listed here, 
feel free

Review Comment:
   I'm not sure what you mean by "they are not listed here". Does this mean the 
toolchains plugin can't locate the JDK? 



##########
src/site/apt/toolchains/discovery.apt.vm:
##########
@@ -0,0 +1,148 @@
+~~ Licensed to the Apache Software Foundation (ASF) under one
+~~ or more contributor license agreements.  See the NOTICE file
+~~ distributed with this work for additional information
+~~ regarding copyright ownership.  The ASF licenses this file
+~~ to you under the Apache License, Version 2.0 (the
+~~ "License"); you may not use this file except in compliance
+~~ with the License.  You may obtain a copy of the License at
+~~
+~~ http://www.apache.org/licenses/LICENSE-2.0
+~~
+~~ Unless required by applicable law or agreed to in writing,
+~~ software distributed under the License is distributed on an
+~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+~~ KIND, either express or implied.  See the License for the
+~~ specific language governing permissions and limitations
+~~ under the License.
+
+  ------
+  Discovery mechanism
+  ------
+  Guillaume Nodet
+  ------
+  2024-02-28
+  ------
+
+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:${project.version}: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 JDK using standard tools and they are not listed here, 
feel free
+  to {{{../issue-management.html}raise an issue}}.
+
+  The discovery mechanism provides a few 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 discovering and selecting a matching JDK.

Review Comment:
   discovering and selecting --> finds



##########
src/main/java/org/apache/maven/plugins/toolchain/jdk/SelectJdkToolchainMojo.java:
##########
@@ -0,0 +1,265 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.plugins.toolchain.jdk;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.stream.Stream;
+
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.toolchain.MisconfiguredToolchainException;
+import org.apache.maven.toolchain.RequirementMatcherFactory;
+import org.apache.maven.toolchain.ToolchainFactory;
+import org.apache.maven.toolchain.ToolchainManagerPrivate;
+import org.apache.maven.toolchain.ToolchainPrivate;
+import org.apache.maven.toolchain.model.PersistedToolchains;
+import org.apache.maven.toolchain.model.ToolchainModel;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+
+import static org.apache.maven.plugins.toolchain.jdk.ToolchainDiscoverer.ENV;
+import static 
org.apache.maven.plugins.toolchain.jdk.ToolchainDiscoverer.RUNTIME_NAME;
+import static 
org.apache.maven.plugins.toolchain.jdk.ToolchainDiscoverer.RUNTIME_VERSION;
+import static 
org.apache.maven.plugins.toolchain.jdk.ToolchainDiscoverer.VENDOR;
+import static 
org.apache.maven.plugins.toolchain.jdk.ToolchainDiscoverer.VERSION;
+
+/**
+ * Discover JDK toolchains and select a matching one.
+ */
+@Mojo(name = "select-jdk-toolchain", defaultPhase = LifecyclePhase.VALIDATE)
+public class SelectJdkToolchainMojo extends AbstractMojo {
+
+    public static final String TOOLCHAIN_TYPE_JDK = "jdk";
+
+    /** Jdk usage mode */
+    public enum JdkMode {
+        /** always ignore the current JDK */
+        Never,
+        /** to not use a toolchain if the toolchains that would be selected is 
the current JDK */
+        IfSame,
+        /** favor the current JDK if it matches the requirements */
+        IfMatch
+    }
+
+    /**
+     * The version constraint for the JDK toolchain to select.
+     */
+    @Parameter(property = "toolchain.jdk.version")
+    private String version;
+
+    /**
+     * The runtime name constraint for the JDK toolchain to select.
+     */
+    @Parameter(property = "toolchain.jdk.runtime.name")
+    private String runtimeName;
+
+    /**
+     * The runtime version constraint for the JDK toolchain to select.
+     */
+    @Parameter(property = "toolchain.jdk.runtime.version")
+    private String runtimeVersion;
+
+    /**
+     * The vendor constraint for the JDK toolchain to select.
+     */
+    @Parameter(property = "toolchain.jdk.vendor")
+    private String vendor;
+
+    /**
+     * The env constraint for the JDK toolchain to select.
+     * To match the constraint, an environment variable with the given name 
must point to the JDK.
+     * For example, if you define {@code JAVA11_HOME=~/jdks/my-jdk-11.0.1}, 
you can specify
+     * {@code env=JAVA11_HOME} to match the given JDK.
+     */
+    @Parameter(property = "toolchain.jdk.env")
+    private String env;
+
+    /**
+     * The matching mode, either {@code IfMatch} (the default), {@code 
IfSame}, or {@code Never}.
+     * If {@code IfMatch} is used, a toolchain will not be selected if the 
running JDK does
+     * match the provided constraints. This is the default and provides better 
performances as it
+     * avoids forking a different process when it's not required. The {@code 
IfSame} avoids
+     * selecting a toolchain if the toolchain selected is exactly the same as 
the running JDK.
+     * THe {@code Never} option will always select the toolchain.
+     */
+    @Parameter(property = "toolchain.jdk.mode", defaultValue = "IfMatch")
+    private JdkMode useJdk = JdkMode.IfMatch;
+
+    /**
+     * Automatically discover JDK toolchains using the built-in heuristic.
+     * The default value is {@code true}.
+     */
+    @Parameter(property = "toolchain.jdk.discover", defaultValue = "true")
+    private boolean discoverToolchains = true;
+
+    /**
+     * Comparator used to sort JDK toolchains for selection.
+     * This property is a comma separated list of values which may contains:
+     * <ul>
+     * <li>{@code lts}: prefer JDK with LTS version</li>
+     * <li>{@code current}: prefer the current JDK</li>
+     * <li>{@code env}: prefer JDKs defined using {@code JAVA\{xx\}_HOME} 
environment variables</li>
+     * <li>{@code version}: prefer JDK with higher versions</li>
+     * <li>{@code vendor}: order JDK by vendor name (usually as a last 
comparator to ensure a stable order)</li>
+     * </ul>
+     */
+    @Parameter(property = "toolchain.jdk.comparator", defaultValue = 
"lts,current,env,version,vendor")
+    private String comparator;
+
+    /**
+     * Toolchain manager
+     */
+    @Inject
+    private ToolchainManagerPrivate toolchainManager;
+
+    /**
+     * Toolchain factory
+     */
+    @Inject
+    @Named(TOOLCHAIN_TYPE_JDK)
+    ToolchainFactory factory;
+
+    /**
+     * The current build session instance. This is used for toolchain manager 
API calls.
+     */
+    @Inject
+    private MavenSession session;
+
+    /**
+     * Toolchain discoverer
+     */
+    @Inject
+    ToolchainDiscoverer discoverer;
+
+    @Override
+    public void execute() throws MojoFailureException {
+        try {
+            doExecute();
+        } catch (MisconfiguredToolchainException e) {
+            throw new MojoFailureException("Unable to select toolchain: " + e, 
e);
+        }
+    }
+
+    private void doExecute() throws MisconfiguredToolchainException, 
MojoFailureException {
+        if (version == null && runtimeName == null && runtimeVersion == null 
&& vendor == null && env == null) {
+            return;
+        }
+
+        Map<String, String> requirements = new HashMap<>();
+        Optional.ofNullable(version).ifPresent(v -> requirements.put(VERSION, 
v));
+        Optional.ofNullable(runtimeName).ifPresent(v -> 
requirements.put(RUNTIME_NAME, v));
+        Optional.ofNullable(runtimeVersion).ifPresent(v -> 
requirements.put(RUNTIME_VERSION, v));
+        Optional.ofNullable(vendor).ifPresent(v -> requirements.put(VENDOR, 
v));
+        Optional.ofNullable(env).ifPresent(v -> requirements.put(ENV, v));
+
+        ToolchainModel currentJdkToolchainModel =
+                discoverer.getCurrentJdkToolchain().orElse(null);
+        ToolchainPrivate currentJdkToolchain =
+                currentJdkToolchainModel != null ? 
factory.createToolchain(currentJdkToolchainModel) : null;
+
+        if (useJdk == JdkMode.IfMatch && currentJdkToolchain != null && 
matches(currentJdkToolchain, requirements)) {
+            getLog().info("Not using an external toolchain as the current JDK 
matches the requirements.");
+            return;
+        }
+
+        ToolchainPrivate toolchain = 
Stream.of(toolchainManager.getToolchainsForType(TOOLCHAIN_TYPE_JDK, session))
+                .filter(tc -> matches(tc, requirements))
+                .findFirst()
+                .orElse(null);
+        if (toolchain != null) {
+            getLog().info("Found matching JDK toolchain: " + toolchain);
+        }
+
+        if (toolchain == null && discoverToolchains) {
+            getLog().debug("No matching toolchains configured, trying to 
discover JDK toolchains");
+            PersistedToolchains persistedToolchains = 
discoverer.discoverToolchains(comparator);
+            getLog().info("Discovered " + 
persistedToolchains.getToolchains().size() + " JDK toolchains");
+
+            for (ToolchainModel tcm : persistedToolchains.getToolchains()) {
+                ToolchainPrivate tc = factory.createToolchain(tcm);
+                if (tc != null && matches(tc, requirements)) {
+                    toolchain = tc;
+                    getLog().debug("Discovered matching JDK toolchain: " + 
toolchain);
+                    break;
+                }
+            }
+        }
+
+        if (toolchain == null) {
+            throw new MojoFailureException(
+                    "Cannot find matching toolchain definitions for the 
following toolchain types:" + requirements
+                            + System.lineSeparator()
+                            + "Please make sure you define the required 
toolchains in your ~/.m2/toolchains.xml file.");
+        }
+
+        if (useJdk == JdkMode.IfSame
+                && currentJdkToolchain != null
+                && Objects.equals(getJdkHome(currentJdkToolchain), 
getJdkHome(toolchain))) {
+            getLog().info("Not using an external toolchain as the current JDK 
has been selected.");

Review Comment:
   debug



##########
src/site/apt/toolchains/discovery.apt.vm:
##########
@@ -0,0 +1,148 @@
+~~ Licensed to the Apache Software Foundation (ASF) under one
+~~ or more contributor license agreements.  See the NOTICE file
+~~ distributed with this work for additional information
+~~ regarding copyright ownership.  The ASF licenses this file
+~~ to you under the Apache License, Version 2.0 (the
+~~ "License"); you may not use this file except in compliance
+~~ with the License.  You may obtain a copy of the License at
+~~
+~~ http://www.apache.org/licenses/LICENSE-2.0
+~~
+~~ Unless required by applicable law or agreed to in writing,
+~~ software distributed under the License is distributed on an
+~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+~~ KIND, either express or implied.  See the License for the
+~~ specific language governing permissions and limitations
+~~ under the License.
+
+  ------
+  Discovery mechanism
+  ------
+  Guillaume Nodet
+  ------
+  2024-02-28
+  ------
+
+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:${project.version}: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 JDK using standard tools and they are not listed here, 
feel free
+  to {{{../issue-management.html}raise an issue}}.
+
+  The discovery mechanism provides a few 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 discovering and selecting a matching JDK.
+  The config below allows using the current JDK, or any other discovered JDK 
>= 17.
+  The benefit is that the current JDK can be kept for speed, but ensuring the 
usage of any JDK 17 or higher if
+  the current jdk is below the requirements.
+
++---+
+<properties>
+  <toolchain.jdk.version>[17,)</toolchain.jdk.version>
+<properties>
+
+<plugin>
+  <groupId>org.apache.maven.plugins</groupId>
+  <artifactId>maven-toolchains-plugin</artifactId>
+  <version>${project.version}</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>
++---+
+
+* Selection mechanism
+
+  Several properties can be used to 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 match the above requirements.  In 
such a case, you may want to express
+  preferences to use to sort the toolchains.  This can be done using the 
<<<comparator>>> configuration which is a
+  comma separated list of criterions 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 toolchains.
+  The <<<select-jdk-toolchain>>> will select a toolchain amongst explicitly 
configured toolchains and discovered
+  toolchains. The information for discovered toolchains are cached in 
<<<~/.m2/discovered-toolchains-cache.xml>>> file
+  by default, to speed up things.

Review Comment:
   things --> builds



##########
src/site/apt/toolchains/discovery.apt.vm:
##########
@@ -0,0 +1,148 @@
+~~ Licensed to the Apache Software Foundation (ASF) under one
+~~ or more contributor license agreements.  See the NOTICE file
+~~ distributed with this work for additional information
+~~ regarding copyright ownership.  The ASF licenses this file
+~~ to you under the Apache License, Version 2.0 (the
+~~ "License"); you may not use this file except in compliance
+~~ with the License.  You may obtain a copy of the License at
+~~
+~~ http://www.apache.org/licenses/LICENSE-2.0
+~~
+~~ Unless required by applicable law or agreed to in writing,
+~~ software distributed under the License is distributed on an
+~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+~~ KIND, either express or implied.  See the License for the
+~~ specific language governing permissions and limitations
+~~ under the License.
+
+  ------
+  Discovery mechanism
+  ------
+  Guillaume Nodet
+  ------
+  2024-02-28
+  ------
+
+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:${project.version}: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 JDK using standard tools and they are not listed here, 
feel free
+  to {{{../issue-management.html}raise an issue}}.
+
+  The discovery mechanism provides a few 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 discovering and selecting a matching JDK.
+  The config below allows using the current JDK, or any other discovered JDK 
>= 17.
+  The benefit is that the current JDK can be kept for speed, but ensuring the 
usage of any JDK 17 or higher if
+  the current jdk is below the requirements.
+
++---+
+<properties>
+  <toolchain.jdk.version>[17,)</toolchain.jdk.version>
+<properties>
+
+<plugin>
+  <groupId>org.apache.maven.plugins</groupId>
+  <artifactId>maven-toolchains-plugin</artifactId>
+  <version>${project.version}</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>
++---+
+
+* Selection mechanism
+
+  Several properties can be used to 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 match the above requirements.  In 
such a case, you may want to express

Review Comment:
   may match the above requirements --> match satisfy the requirements
   may want to --> can
   to use to sort -> for sorting



##########
src/site/apt/toolchains/discovery.apt.vm:
##########
@@ -0,0 +1,148 @@
+~~ Licensed to the Apache Software Foundation (ASF) under one
+~~ or more contributor license agreements.  See the NOTICE file
+~~ distributed with this work for additional information
+~~ regarding copyright ownership.  The ASF licenses this file
+~~ to you under the Apache License, Version 2.0 (the
+~~ "License"); you may not use this file except in compliance
+~~ with the License.  You may obtain a copy of the License at
+~~
+~~ http://www.apache.org/licenses/LICENSE-2.0
+~~
+~~ Unless required by applicable law or agreed to in writing,
+~~ software distributed under the License is distributed on an
+~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+~~ KIND, either express or implied.  See the License for the
+~~ specific language governing permissions and limitations
+~~ under the License.
+
+  ------
+  Discovery mechanism
+  ------
+  Guillaume Nodet
+  ------
+  2024-02-28
+  ------
+
+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:${project.version}: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 JDK using standard tools and they are not listed here, 
feel free
+  to {{{../issue-management.html}raise an issue}}.
+
+  The discovery mechanism provides a few 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 discovering and selecting a matching JDK.
+  The config below allows using the current JDK, or any other discovered JDK 
>= 17.
+  The benefit is that the current JDK can be kept for speed, but ensuring the 
usage of any JDK 17 or higher if
+  the current jdk is below the requirements.
+
++---+
+<properties>
+  <toolchain.jdk.version>[17,)</toolchain.jdk.version>
+<properties>
+
+<plugin>
+  <groupId>org.apache.maven.plugins</groupId>
+  <artifactId>maven-toolchains-plugin</artifactId>
+  <version>${project.version}</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>
++---+
+
+* Selection mechanism
+
+  Several properties can be used to 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 match the above requirements.  In 
such a case, you may want to express
+  preferences to use to sort the toolchains.  This can be done using the 
<<<comparator>>> configuration which is a
+  comma separated list of criterions 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 toolchains.
+  The <<<select-jdk-toolchain>>> will select a toolchain amongst explicitly 
configured toolchains and discovered
+  toolchains. The information for discovered toolchains are cached in 
<<<~/.m2/discovered-toolchains-cache.xml>>> file

Review Comment:
   The information for discovered --> Discovered



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to