From 42749ff1865a2981a8e61d94370a01feb7de9943 Mon Sep 17 00:00:00 2001 From: Slawomir Jaranowski Date: Mon, 20 Apr 2026 19:28:46 +0200 Subject: [PATCH] Promote java version in JavaToolchain Many plugins using toolchains has requirements to detect java version selected by toolchains in runtime. Expose java version in JavaToolchain can simplify plugins code. --- .../maven/toolchain/java/JavaToolchain.java | 15 +++ .../toolchain/java/JavaToolchainFactory.java | 13 ++- .../toolchain/java/JavaToolchainImpl.java | 12 +++ .../java/JavaToolchainFactoryTest.java | 92 +++++++++++++++++++ 4 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 maven-core/src/test/java/org/apache/maven/toolchain/java/JavaToolchainFactoryTest.java diff --git a/maven-core/src/main/java/org/apache/maven/toolchain/java/JavaToolchain.java b/maven-core/src/main/java/org/apache/maven/toolchain/java/JavaToolchain.java index 23fa8c7e8152..4bf8375942f2 100644 --- a/maven-core/src/main/java/org/apache/maven/toolchain/java/JavaToolchain.java +++ b/maven-core/src/main/java/org/apache/maven/toolchain/java/JavaToolchain.java @@ -18,6 +18,7 @@ */ package org.apache.maven.toolchain.java; +import org.apache.maven.artifact.versioning.ArtifactVersion; import org.apache.maven.toolchain.Toolchain; /** @@ -61,4 +62,18 @@ public interface JavaToolchain extends Toolchain { // * @return List // */ // List getJavadocDirectories(); + + /** + * Returns the home directory of the JDK. + * + * @since 3.10.0 + */ + String getJavaHome(); + + /** + * Returns the version of the JDK. + * + * @since 3.10.0 + */ + ArtifactVersion getJavaVersion(); } diff --git a/maven-core/src/main/java/org/apache/maven/toolchain/java/JavaToolchainFactory.java b/maven-core/src/main/java/org/apache/maven/toolchain/java/JavaToolchainFactory.java index 292461818d69..aed98d97b018 100644 --- a/maven-core/src/main/java/org/apache/maven/toolchain/java/JavaToolchainFactory.java +++ b/maven-core/src/main/java/org/apache/maven/toolchain/java/JavaToolchainFactory.java @@ -23,9 +23,12 @@ import javax.inject.Singleton; import java.io.File; +import java.util.Map; import java.util.Map.Entry; import java.util.Properties; +import org.apache.maven.artifact.versioning.ArtifactVersion; +import org.apache.maven.artifact.versioning.DefaultArtifactVersion; import org.apache.maven.toolchain.MisconfiguredToolchainException; import org.apache.maven.toolchain.RequirementMatcher; import org.apache.maven.toolchain.RequirementMatcherFactory; @@ -84,7 +87,7 @@ public ToolchainPrivate createToolchain(ToolchainModel model) throws Misconfigur // populate the configuration section Xpp3Dom dom = (Xpp3Dom) model.getConfiguration(); - Xpp3Dom javahome = dom.getChild(JavaToolchainImpl.KEY_JAVAHOME); + Xpp3Dom javahome = dom != null ? dom.getChild(JavaToolchainImpl.KEY_JAVAHOME) : null; if (javahome == null) { throw new MisconfiguredToolchainException( "Java toolchain without the " + JavaToolchainImpl.KEY_JAVAHOME + " configuration element."); @@ -97,6 +100,14 @@ public ToolchainPrivate createToolchain(ToolchainModel model) throws Misconfigur "Non-existing JDK home configuration at " + normal.getAbsolutePath()); } + ArtifactVersion javaVersion = model.getProvides().entrySet().stream() + .filter(entry -> "version".equals(entry.getKey())) + .map(Map.Entry::getValue) + .map(v -> new DefaultArtifactVersion((String) v)) + .findAny() + .orElse(null); + + jtc.setJavaVersion(javaVersion); return jtc; } diff --git a/maven-core/src/main/java/org/apache/maven/toolchain/java/JavaToolchainImpl.java b/maven-core/src/main/java/org/apache/maven/toolchain/java/JavaToolchainImpl.java index e5c2e434d869..35d0edd79f76 100644 --- a/maven-core/src/main/java/org/apache/maven/toolchain/java/JavaToolchainImpl.java +++ b/maven-core/src/main/java/org/apache/maven/toolchain/java/JavaToolchainImpl.java @@ -20,6 +20,7 @@ import java.io.File; +import org.apache.maven.artifact.versioning.ArtifactVersion; import org.apache.maven.toolchain.DefaultToolchain; import org.apache.maven.toolchain.model.ToolchainModel; import org.codehaus.plexus.logging.Logger; @@ -35,6 +36,8 @@ public class JavaToolchainImpl extends DefaultToolchain implements JavaToolchain { private String javaHome; + private ArtifactVersion javaVersion; + public static final String KEY_JAVAHOME = "jdkHome"; // NOI18N JavaToolchainImpl(ToolchainModel model, Logger logger) { @@ -49,6 +52,15 @@ public void setJavaHome(String javaHome) { this.javaHome = javaHome; } + @Override + public ArtifactVersion getJavaVersion() { + return javaVersion; + } + + public void setJavaVersion(ArtifactVersion javaVersion) { + this.javaVersion = javaVersion; + } + public String toString() { return "JDK[" + getJavaHome() + "]"; } diff --git a/maven-core/src/test/java/org/apache/maven/toolchain/java/JavaToolchainFactoryTest.java b/maven-core/src/test/java/org/apache/maven/toolchain/java/JavaToolchainFactoryTest.java new file mode 100644 index 000000000000..dda69fdd5600 --- /dev/null +++ b/maven-core/src/test/java/org/apache/maven/toolchain/java/JavaToolchainFactoryTest.java @@ -0,0 +1,92 @@ +/* + * 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.toolchain.java; + +import org.apache.maven.toolchain.MisconfiguredToolchainException; +import org.apache.maven.toolchain.model.ToolchainModel; +import org.codehaus.plexus.util.xml.Xpp3Dom; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class JavaToolchainFactoryTest { + private JavaToolchainFactory factory; + + @BeforeEach + void setup() { + factory = new JavaToolchainFactory(); + } + + @Test + void defaultToolchainShouldReturnEmpty() { + assertNull(factory.createDefaultToolchain()); + } + + @Test + void missingJdkHomeShouldThrowException() { + ToolchainModel toolchainModel = new ToolchainModel(); + MisconfiguredToolchainException exception = Assertions.assertThrows( + MisconfiguredToolchainException.class, () -> factory.createToolchain(toolchainModel)); + assertEquals("Java toolchain without the jdkHome configuration element.", exception.getMessage()); + } + + @Test + void nonExistingJdkHomeShouldThrowException() { + ToolchainModel toolchainModel = new ToolchainModel(); + Xpp3Dom jdkHome = new Xpp3Dom("jdkHome"); + jdkHome.setValue("/not-exist/jdk/home"); + Xpp3Dom configuration = new Xpp3Dom("configuration"); + configuration.addChild(jdkHome); + toolchainModel.setConfiguration(configuration); + + MisconfiguredToolchainException exception = Assertions.assertThrows( + MisconfiguredToolchainException.class, () -> factory.createToolchain(toolchainModel)); + assertTrue( + exception.getMessage().contains("Non-existing JDK home configuration at"), + "Not expected exception message: '" + exception.getMessage()); + assertTrue( + exception.getMessage().contains("not-exist"), + "Not expected exception message: '" + exception.getMessage() + "', should contain: 'not-exist'"); + } + + @Test + void properToolchainShouldReturnJavaToolchain() throws Exception { + String javaHome = System.getProperty("java.home"); + String javaVersion = System.getProperty("java.version"); + + ToolchainModel toolchainModel = new ToolchainModel(); + Xpp3Dom jdkHome = new Xpp3Dom("jdkHome"); + jdkHome.setValue(javaHome); + Xpp3Dom configuration = new Xpp3Dom("configuration"); + configuration.addChild(jdkHome); + toolchainModel.setConfiguration(configuration); + + toolchainModel.addProvide("version", javaVersion); + + JavaToolchain toolchain = (JavaToolchain) factory.createToolchain(toolchainModel); + assertNotNull(toolchain); + assertEquals(javaHome, toolchain.getJavaHome()); + assertEquals(javaVersion, toolchain.getJavaVersion().toString()); + } +}