From cd933db27a27d7aae8c133a0cd43478544675acb Mon Sep 17 00:00:00 2001 From: Neil Bartlett Date: Sun, 12 Apr 2020 13:40:11 +0100 Subject: [PATCH] Use Maven Toolchain in native-image-maven-plugin This adds support for Maven Toolchains in the native-image-plugin. Toolchains are the best practice for multi-module Maven projects where each module may need to build with a different Java version. For example, in a shared library project one might want to build most modules using a conservatively low Java version such as 1.8, to allow those libraries to be used by a larger population of developers. But within the same multi-module project you might have a "leaf" module that builds a standalone application and exports that application as an executable using GraalVM native-image. Toolchains allow each module to define the JDK flavour and version it requires. Toolchains are supported by all the basic Maven plugins such as maven-compiler-plugin, maven-surefire-plugin etc. Since the native-image plugin does not currently support toolchains, we have to run the entire Maven build using GraalVM as the JAVA_HOME, which may not work for some projects. To use this support, we can define a section in our $HOME/.m2/toolchains.xml such as: jdk JavaSE-11 11 GraalVM /Library/Java/JavaVirtualMachines/graalvm-ce-java11-20.0.0/Contents/Home Then in a module that uses GraalVM native-image we declare: maven-toolchains-plugin 11 GraalVM Note that if a module does not declare toolchain support, then the native-image-maven-plugin falls back to its existing mechanism, i.e. picking up the JAVA_HOME used to run Maven itself. Therefore, there will be no effect on existing projects that do not opt-in to using toolchains. --- .../oracle/substratevm/NativeImageMojo.java | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/substratevm/src/native-image-maven-plugin/src/main/java/com/oracle/substratevm/NativeImageMojo.java b/substratevm/src/native-image-maven-plugin/src/main/java/com/oracle/substratevm/NativeImageMojo.java index 20eb311a2fac..f167720df6e8 100644 --- a/substratevm/src/native-image-maven-plugin/src/main/java/com/oracle/substratevm/NativeImageMojo.java +++ b/substratevm/src/native-image-maven-plugin/src/main/java/com/oracle/substratevm/NativeImageMojo.java @@ -36,12 +36,14 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Optional; import java.util.Scanner; import java.util.ServiceLoader; import java.util.stream.Collectors; import java.util.stream.Stream; import org.apache.maven.artifact.Artifact; +import org.apache.maven.execution.MavenSession; import org.apache.maven.model.ConfigurationContainer; import org.apache.maven.model.Plugin; import org.apache.maven.model.PluginExecution; @@ -49,9 +51,12 @@ import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.descriptor.PluginDescriptor; import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.project.MavenProject; +import org.apache.maven.toolchain.ToolchainManager; +import org.apache.maven.toolchain.java.DefaultJavaToolChain; import org.codehaus.plexus.archiver.tar.TarGZipUnArchiver; import org.codehaus.plexus.logging.AbstractLogger; import org.codehaus.plexus.logging.Logger; @@ -88,6 +93,12 @@ public class NativeImageMojo extends AbstractMojo { @Parameter(property = "skip", defaultValue = "false")// private boolean skip; + @Parameter(defaultValue = "${session}", readonly = true)// + private MavenSession session; + + @Component + private ToolchainManager toolchainManager; + private Logger tarGzLogger = new AbstractLogger(Logger.LEVEL_WARN, "NativeImageMojo.tarGzLogger") { @Override public void debug(String message, Throwable throwable) { @@ -302,8 +313,12 @@ private void addClasspath(Artifact artifact) throws MojoExecutionException { classpath.add(jarFilePath); } - private static Path getMojoJavaHome() { - return Paths.get(System.getProperty("java.home")); + private Path getMojoJavaHome() { + return Paths.get(Optional.ofNullable(toolchainManager) + .map(tm -> tm.getToolchainFromBuildContext("jdk", session)) + .filter(DefaultJavaToolChain.class::isInstance).map(DefaultJavaToolChain.class::cast) + .map(DefaultJavaToolChain::getJavaHome) + .orElse(System.getProperty("java.home"))); } private Path getWorkingDirectory() {