[ 
https://issues.apache.org/jira/browse/MTOOLCHAINS-49?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17822251#comment-17822251
 ] 

ASF GitHub Bot commented on MTOOLCHAINS-49:
-------------------------------------------

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





> Automatic discovery of JDK toolchains
> -------------------------------------
>
>                 Key: MTOOLCHAINS-49
>                 URL: https://issues.apache.org/jira/browse/MTOOLCHAINS-49
>             Project: Maven Toolchains Plugin
>          Issue Type: Improvement
>            Reporter: Guillaume Nodet
>            Assignee: Guillaume Nodet
>            Priority: Major
>




--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to