[
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)