diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/JavaToolchain.java b/api/maven-api-core/src/main/java/org/apache/maven/api/JavaToolchain.java index a4addddac79a..5357af9ac4e9 100644 --- a/api/maven-api-core/src/main/java/org/apache/maven/api/JavaToolchain.java +++ b/api/maven-api-core/src/main/java/org/apache/maven/api/JavaToolchain.java @@ -42,4 +42,6 @@ public interface JavaToolchain extends Toolchain { String getJavaHome(); + + Version getJavaVersion(); } diff --git a/compat/maven-compat/src/main/java/org/apache/maven/toolchain/java/JavaToolchain.java b/compat/maven-compat/src/main/java/org/apache/maven/toolchain/java/JavaToolchain.java index 6080f00f4d79..300f80f75f2e 100644 --- a/compat/maven-compat/src/main/java/org/apache/maven/toolchain/java/JavaToolchain.java +++ b/compat/maven-compat/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; /** @@ -27,4 +28,8 @@ * @deprecated Use {@link org.apache.maven.api.JavaToolchain} instead. */ @Deprecated(since = "4.0.0") -public interface JavaToolchain extends Toolchain {} +public interface JavaToolchain extends Toolchain { + String getJavaHome(); + + ArtifactVersion getJavaVersion(); +} diff --git a/compat/maven-compat/src/main/java/org/apache/maven/toolchain/java/JavaToolchainFactory.java b/compat/maven-compat/src/main/java/org/apache/maven/toolchain/java/JavaToolchainFactory.java index f22884ce6494..3802b45538c4 100644 --- a/compat/maven-compat/src/main/java/org/apache/maven/toolchain/java/JavaToolchainFactory.java +++ b/compat/maven-compat/src/main/java/org/apache/maven/toolchain/java/JavaToolchainFactory.java @@ -21,9 +21,12 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +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; @@ -93,6 +96,14 @@ public ToolchainPrivate createToolchain(ToolchainModel model) throws Misconfigur "Non-existing JDK home configuration at " + normal.toAbsolutePath()); } + 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/compat/maven-compat/src/main/java/org/apache/maven/toolchain/java/JavaToolchainImpl.java b/compat/maven-compat/src/main/java/org/apache/maven/toolchain/java/JavaToolchainImpl.java index 661ffa642455..c4a837c07b2b 100644 --- a/compat/maven-compat/src/main/java/org/apache/maven/toolchain/java/JavaToolchainImpl.java +++ b/compat/maven-compat/src/main/java/org/apache/maven/toolchain/java/JavaToolchainImpl.java @@ -22,6 +22,7 @@ import java.nio.file.Path; import java.nio.file.Paths; +import org.apache.maven.artifact.versioning.ArtifactVersion; import org.apache.maven.toolchain.DefaultToolchain; import org.apache.maven.toolchain.model.ToolchainModel; import org.apache.maven.utils.Os; @@ -39,6 +40,8 @@ public class JavaToolchainImpl extends DefaultToolchain implements JavaToolchain public static final String KEY_JAVAHOME = "jdkHome"; // NOI18N + private ArtifactVersion javaVersion; + JavaToolchainImpl(ToolchainModel model, Logger logger) { super(model, "jdk", logger); } @@ -47,6 +50,15 @@ public String getJavaHome() { return javaHome; } + @Override + public ArtifactVersion getJavaVersion() { + return javaVersion; + } + + public void setJavaVersion(ArtifactVersion javaVersion) { + this.javaVersion = javaVersion; + } + public void setJavaHome(String javaHome) { this.javaHome = javaHome; } diff --git a/compat/maven-compat/src/test/java/org/apache/maven/toolchain/java/JavaToolchainFactoryTest.java b/compat/maven-compat/src/test/java/org/apache/maven/toolchain/java/JavaToolchainFactoryTest.java new file mode 100644 index 000000000000..8589426f1b08 --- /dev/null +++ b/compat/maven-compat/src/test/java/org/apache/maven/toolchain/java/JavaToolchainFactoryTest.java @@ -0,0 +1,94 @@ +/* + * 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; + +@SuppressWarnings("deprecation") +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()); + } +} diff --git a/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultJavaToolchainFactory.java b/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultJavaToolchainFactory.java index 2d1383904286..d307b507a0b8 100644 --- a/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultJavaToolchainFactory.java +++ b/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultJavaToolchainFactory.java @@ -87,7 +87,14 @@ public JavaToolchain createToolchain(@Nonnull ToolchainModel model) { } String javaHome = normal.toString(); - return new DefaultJavaToolchain(model, javaHome, matchers); + Version javaVersion = model.getProvides().entrySet().stream() + .filter(entry -> "version".equals(entry.getKey())) + .map(Map.Entry::getValue) + .map(versionParser::parseVersion) + .findAny() + .orElse(null); + + return new DefaultJavaToolchain(model, javaHome, javaVersion, matchers); } @Nonnull @@ -102,9 +109,13 @@ static class DefaultJavaToolchain implements JavaToolchain { final String javaHome; final Map> matchers; - DefaultJavaToolchain(ToolchainModel model, String javaHome, Map> matchers) { + private Version javaVersion; + + DefaultJavaToolchain( + ToolchainModel model, String javaHome, Version javaVersion, Map> matchers) { this.model = model; this.javaHome = javaHome; + this.javaVersion = javaVersion; this.matchers = matchers; } @@ -113,6 +124,11 @@ public String getJavaHome() { return javaHome; } + @Override + public Version getJavaVersion() { + return javaVersion; + } + @Override public String getType() { return "jdk"; diff --git a/impl/maven-impl/src/test/java/org/apache/maven/impl/DefaultJavaToolchainFactoryTest.java b/impl/maven-impl/src/test/java/org/apache/maven/impl/DefaultJavaToolchainFactoryTest.java new file mode 100644 index 000000000000..387d08f65bbc --- /dev/null +++ b/impl/maven-impl/src/test/java/org/apache/maven/impl/DefaultJavaToolchainFactoryTest.java @@ -0,0 +1,97 @@ +/* + * 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.impl; + +import java.util.List; +import java.util.Map; + +import org.apache.maven.api.JavaToolchain; +import org.apache.maven.api.services.ToolchainFactoryException; +import org.apache.maven.api.services.VersionParser; +import org.apache.maven.api.toolchain.ToolchainModel; +import org.apache.maven.api.xml.XmlNode; +import org.apache.maven.impl.resolver.MavenVersionScheme; +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.assertTrue; + +class DefaultJavaToolchainFactoryTest { + + private DefaultJavaToolchainFactory factory; + + @BeforeEach + void setUp() { + VersionParser versionParser = new DefaultVersionParser(new DefaultModelVersionParser(new MavenVersionScheme())); + factory = new DefaultJavaToolchainFactory(versionParser); + } + + @Test + void defaultToolchainShouldReturnEmpty() { + assertTrue(factory.createDefaultToolchain().isEmpty()); + } + + @Test + void missingJdkHomeShouldThrowException() { + ToolchainModel toolchainModel = ToolchainModel.newBuilder().build(); + ToolchainFactoryException exception = + Assertions.assertThrows(ToolchainFactoryException.class, () -> factory.createToolchain(toolchainModel)); + assertEquals("Java toolchain without the jdkHome configuration element.", exception.getMessage()); + } + + @Test + void nonExistingJdkHomeShouldThrowException() { + ToolchainModel toolchainModel = ToolchainModel.newBuilder() + .configuration(XmlNode.newBuilder() + .name("configuration") + .children(List.of(XmlNode.newInstance("jdkHome", "/not-exist/jdk/home"))) + .build()) + .build(); + + ToolchainFactoryException exception = + Assertions.assertThrows(ToolchainFactoryException.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() { + String javaHome = System.getProperty("java.home"); + String javaVersion = System.getProperty("java.version"); + ToolchainModel toolchainModel = ToolchainModel.newBuilder() + .provides(Map.of("version", javaVersion)) + .configuration(XmlNode.newBuilder() + .name("configuration") + .children(List.of(XmlNode.newInstance("jdkHome", javaHome))) + .build()) + .build(); + + JavaToolchain toolchain = factory.createToolchain(toolchainModel); + assertNotNull(toolchain); + assertEquals(javaHome, toolchain.getJavaHome()); + assertEquals(javaVersion, toolchain.getJavaVersion().toString()); + } +}