This is an automated email from the ASF dual-hosted git repository.
rfscholte pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-jlink-plugin.git
The following commit(s) were added to refs/heads/master by this push:
new f8bdf50 Java 9+ ToolProvider via multi-release jar.
f8bdf50 is described below
commit f8bdf5050c266854524aaa51eb36109c00ca692a
Author: Benjamin Marwell <[email protected]>
AuthorDate: Tue Nov 24 18:53:35 2020 +0100
Java 9+ ToolProvider via multi-release jar.
Signed-off-by: rfscholte <[email protected]>
---
pom.xml | 47 +++++
.../MJLINK-36_toolchainjdk8/invoker.properties | 20 ++
src/it/projects/MJLINK-36_toolchainjdk8/pom.xml | 95 ++++++++++
.../MJLINK-36_toolchainjdk9/invoker.properties | 20 ++
src/it/projects/MJLINK-36_toolchainjdk9/pom.xml | 95 ++++++++++
.../MJLINK-40_includeLocales/verify.groovy | 16 +-
.../maven/plugins/jlink/AbstractJLinkExecutor.java | 63 +++++++
.../maven/plugins/jlink/AbstractJLinkMojo.java | 154 +---------------
.../jlink/AbstractJLinkToolchainExecutor.java | 204 +++++++++++++++++++++
.../apache/maven/plugins/jlink/JLinkExecutor.java} | 41 ++---
.../org/apache/maven/plugins/jlink/JLinkMojo.java | 160 ++++++----------
.../apache/maven/plugins/jlink/JLinkExecutor.java | 143 +++++++++++++++
12 files changed, 772 insertions(+), 286 deletions(-)
diff --git a/pom.xml b/pom.xml
index da94e29..45e7acc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -199,6 +199,53 @@
</reporting>
<profiles>
<profile>
+ <id>jdk9</id>
+ <activation>
+ <jdk>[9,)</jdk>
+ </activation>
+ <build>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>jdk9</id>
+ <goals>
+ <goal>compile</goal>
+ </goals>
+ <configuration>
+ <release>9</release>
+ <multiReleaseOutput>true</multiReleaseOutput>
+ <compileSourceRoots>
+
<compileSourceRoot>${project.basedir}/src/main/java9</compileSourceRoot>
+ </compileSourceRoots>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>default-jar</id>
+ <configuration>
+ <archive>
+ <manifestEntries>
+ <Multi-Release>true</Multi-Release>
+ </manifestEntries>
+ </archive>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+ </profile>
+ <profile>
<id>run-its</id>
<build>
<plugins>
diff --git a/src/it/projects/MJLINK-36_toolchainjdk8/invoker.properties
b/src/it/projects/MJLINK-36_toolchainjdk8/invoker.properties
new file mode 100644
index 0000000..d3282c7
--- /dev/null
+++ b/src/it/projects/MJLINK-36_toolchainjdk8/invoker.properties
@@ -0,0 +1,20 @@
+# 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.
+
+invoker.java.version = 1.8
+invoker.goals = clean install
+invoker.toolchain.jdk.version = 11
diff --git a/src/it/projects/MJLINK-36_toolchainjdk8/pom.xml
b/src/it/projects/MJLINK-36_toolchainjdk8/pom.xml
new file mode 100644
index 0000000..f6a37cd
--- /dev/null
+++ b/src/it/projects/MJLINK-36_toolchainjdk8/pom.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ 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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.plugins.jlink.its</groupId>
+ <artifactId>mjlink36-toolchain-jdk8</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <packaging>jlink</packaging>
+
+ <properties>
+ <maven.compiler.source>1.9</maven.compiler.source>
+ <maven.compiler.target>1.9</maven.compiler.target>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <!-- use a dependency with a module-info.class -->
+ <artifactId>asm</artifactId>
+ <groupId>org.ow2.asm</groupId>
+ <version>6.0</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-toolchains-plugin</artifactId>
+ <version>1.1</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>toolchain</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <toolchains>
+ <jdk>
+ <version>11</version>
+ </jdk>
+ </toolchains>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jlink-plugin</artifactId>
+ <version>@project.version@</version>
+ <extensions>true</extensions>
+ <configuration>
+ <noHeaderFiles>true</noHeaderFiles>
+ <noManPages>true</noManPages>
+ <verbose>true</verbose>
+ </configuration>
+ </plugin>
+ </plugins>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.8.0</version>
+ <configuration>
+ <source>${maven.compiler.source}</source>
+ <target>${maven.compiler.target}</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+
+</project>
diff --git a/src/it/projects/MJLINK-36_toolchainjdk9/invoker.properties
b/src/it/projects/MJLINK-36_toolchainjdk9/invoker.properties
new file mode 100644
index 0000000..271bf45
--- /dev/null
+++ b/src/it/projects/MJLINK-36_toolchainjdk9/invoker.properties
@@ -0,0 +1,20 @@
+# 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.
+
+invoker.java.version = 9+
+invoker.goals = clean install
+invoker.toolchain.jdk.version = 11
diff --git a/src/it/projects/MJLINK-36_toolchainjdk9/pom.xml
b/src/it/projects/MJLINK-36_toolchainjdk9/pom.xml
new file mode 100644
index 0000000..ab371a9
--- /dev/null
+++ b/src/it/projects/MJLINK-36_toolchainjdk9/pom.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+ 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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.maven.plugins.jlink.its</groupId>
+ <artifactId>mjlink36-toolchain-jdk9</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <packaging>jlink</packaging>
+
+ <properties>
+ <maven.compiler.source>1.9</maven.compiler.source>
+ <maven.compiler.target>1.9</maven.compiler.target>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <!-- use a dependency with a module-info.class -->
+ <artifactId>asm</artifactId>
+ <groupId>org.ow2.asm</groupId>
+ <version>6.0</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-toolchains-plugin</artifactId>
+ <version>1.1</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>toolchain</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <toolchains>
+ <jdk>
+ <version>11</version>
+ </jdk>
+ </toolchains>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jlink-plugin</artifactId>
+ <version>@project.version@</version>
+ <extensions>true</extensions>
+ <configuration>
+ <noHeaderFiles>true</noHeaderFiles>
+ <noManPages>true</noManPages>
+ <verbose>true</verbose>
+ </configuration>
+ </plugin>
+ </plugins>
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.8.0</version>
+ <configuration>
+ <source>${maven.compiler.source}</source>
+ <target>${maven.compiler.target}</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+ </build>
+
+</project>
diff --git a/src/it/projects/MJLINK-40_includeLocales/verify.groovy
b/src/it/projects/MJLINK-40_includeLocales/verify.groovy
index 1887547..c32508b 100644
--- a/src/it/projects/MJLINK-40_includeLocales/verify.groovy
+++ b/src/it/projects/MJLINK-40_includeLocales/verify.groovy
@@ -26,21 +26,15 @@ boolean result = false;
try
{
- File target = new File( basedir, "target" );
- if ( !target.exists() || !target.isDirectory() )
+ File buildLog = new File( basedir, "build.log" );
+ if ( !buildLog.exists() || buildLog.isDirectory() )
{
- System.err.println( "target file is missing or not a directory." );
- return false;
- }
- File jlinkArgs = new File( target, "jlinkArgs" );
- if ( !jlinkArgs.exists() || jlinkArgs.isDirectory() )
- {
- System.err.println( "jlinkArgs file is missing or is a directory." );
+ System.err.println( "build.log file is missing or is a directory." );
return false;
}
- def line = jlinkArgs.eachLine { line ->
- if (line.equals('en,ja,de,*-IN'))
+ def line = buildLog.eachLine { line ->
+ if (line.contains('--include-locales, en,ja,de,*-IN'))
{
result = true;
}
diff --git
a/src/main/java/org/apache/maven/plugins/jlink/AbstractJLinkExecutor.java
b/src/main/java/org/apache/maven/plugins/jlink/AbstractJLinkExecutor.java
new file mode 100644
index 0000000..3213736
--- /dev/null
+++ b/src/main/java/org/apache/maven/plugins/jlink/AbstractJLinkExecutor.java
@@ -0,0 +1,63 @@
+package org.apache.maven.plugins.jlink;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.logging.Log;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Optional;
+
+abstract class AbstractJLinkExecutor
+{
+ protected static final String JMODS = "jmods";
+
+ private final Log log;
+
+ private final List<String> modulesToAdd = new ArrayList<>();
+ private final List<String> modulePaths = new ArrayList<>();
+
+ AbstractJLinkExecutor( Log log )
+ {
+ this.log = log;
+ }
+
+ protected Log getLog()
+ {
+ return this.log;
+ }
+
+ public abstract Optional<File> getJmodsFolder( /* nullable */ File
sourceJdkModules );
+
+ public abstract int executeJlink( List<String> jlinkArgs ) throws
MojoExecutionException;
+
+ public void addAllModules( Collection<String> modulesToAdd )
+ {
+ this.modulesToAdd.addAll( modulesToAdd );
+ }
+
+ public void addAllModulePaths( Collection<String> pathsOfModules )
+ {
+ this.modulePaths.addAll( pathsOfModules );
+ }
+}
diff --git
a/src/main/java/org/apache/maven/plugins/jlink/AbstractJLinkMojo.java
b/src/main/java/org/apache/maven/plugins/jlink/AbstractJLinkMojo.java
index 39e32ac..74bef13 100644
--- a/src/main/java/org/apache/maven/plugins/jlink/AbstractJLinkMojo.java
+++ b/src/main/java/org/apache/maven/plugins/jlink/AbstractJLinkMojo.java
@@ -20,26 +20,19 @@ package org.apache.maven.plugins.jlink;
*/
import java.io.File;
-import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.List;
import java.util.Map;
-import java.util.Properties;
+import java.util.Optional;
-import org.apache.commons.lang3.SystemUtils;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.AbstractMojo;
-import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.toolchain.Toolchain;
import org.apache.maven.toolchain.ToolchainManager;
-import org.codehaus.plexus.util.StringUtils;
-import org.codehaus.plexus.util.cli.CommandLineException;
-import org.codehaus.plexus.util.cli.CommandLineUtils;
-import org.codehaus.plexus.util.cli.Commandline;
/**
* @author Karl Heinz Marbaise <a
href="mailto:[email protected]">[email protected]</a>
@@ -66,139 +59,12 @@ public abstract class AbstractJLinkMojo
@Component
private ToolchainManager toolchainManager;
- protected String getJLinkExecutable()
- throws IOException
+ protected JLinkExecutor getJlinkExecutor()
{
- Toolchain tc = getToolchain();
-
- String jLinkExecutable = null;
- if ( tc != null )
- {
- jLinkExecutable = tc.findTool( "jlink" );
- }
-
- // TODO: Check if there exist a more elegant way?
- String jLinkCommand = "jlink" + ( SystemUtils.IS_OS_WINDOWS ? ".exe" :
"" );
-
- File jLinkExe;
-
- if ( StringUtils.isNotEmpty( jLinkExecutable ) )
- {
- jLinkExe = new File( jLinkExecutable );
-
- if ( jLinkExe.isDirectory() )
- {
- jLinkExe = new File( jLinkExe, jLinkCommand );
- }
-
- if ( SystemUtils.IS_OS_WINDOWS && jLinkExe.getName().indexOf( '.'
) < 0 )
- {
- jLinkExe = new File( jLinkExe.getPath() + ".exe" );
- }
-
- if ( !jLinkExe.isFile() )
- {
- throw new IOException( "The jlink executable '" + jLinkExe +
"' doesn't exist or is not a file." );
- }
- return jLinkExe.getAbsolutePath();
- }
-
- //
----------------------------------------------------------------------
- // Try to find jlink from System.getProperty( "java.home" )
- // By default, System.getProperty( "java.home" ) = JRE_HOME and
JRE_HOME
- // should be in the JDK_HOME
- //
----------------------------------------------------------------------
- jLinkExe = new File( SystemUtils.getJavaHome() + File.separator + ".."
+ File.separator + "bin", jLinkCommand );
-
- //
----------------------------------------------------------------------
- // Try to find javadocExe from JAVA_HOME environment variable
- //
----------------------------------------------------------------------
- if ( !jLinkExe.exists() || !jLinkExe.isFile() )
- {
- Properties env = CommandLineUtils.getSystemEnvVars();
- String javaHome = env.getProperty( "JAVA_HOME" );
- if ( StringUtils.isEmpty( javaHome ) )
- {
- throw new IOException( "The environment variable JAVA_HOME is
not correctly set." );
- }
- if ( !new File( javaHome ).getCanonicalFile().exists()
- || new File( javaHome ).getCanonicalFile().isFile() )
- {
- throw new IOException( "The environment variable JAVA_HOME=" +
javaHome
- + " doesn't exist or is not a valid directory." );
- }
-
- jLinkExe = new File( javaHome + File.separator + "bin",
jLinkCommand );
- }
-
- if ( !jLinkExe.getCanonicalFile().exists() ||
!jLinkExe.getCanonicalFile().isFile() )
- {
- throw new IOException( "The jlink executable '" + jLinkExe
- + "' doesn't exist or is not a file. Verify the JAVA_HOME
environment variable." );
- }
-
- return jLinkExe.getAbsolutePath();
- }
-
- protected void executeCommand( Commandline cmd, File outputDirectory )
- throws MojoExecutionException
- {
- if ( getLog().isDebugEnabled() )
- {
- // no quoted arguments ???
- getLog().debug( CommandLineUtils.toString( cmd.getCommandline()
).replaceAll( "'", "" ) );
- }
-
- CommandLineUtils.StringStreamConsumer err = new
CommandLineUtils.StringStreamConsumer();
- CommandLineUtils.StringStreamConsumer out = new
CommandLineUtils.StringStreamConsumer();
- try
- {
- int exitCode = CommandLineUtils.executeCommandLine( cmd, out, err
);
-
- String output = ( StringUtils.isEmpty( out.getOutput() ) ? null :
'\n' + out.getOutput().trim() );
-
- if ( exitCode != 0 )
- {
-
- if ( StringUtils.isNotEmpty( output ) )
- {
- // Reconsider to use WARN / ERROR ?
- // getLog().error( output );
- for ( String outputLine : output.split( "\n" ) )
- {
- getLog().error( outputLine );
- }
- }
-
- StringBuilder msg = new StringBuilder( "\nExit code: " );
- msg.append( exitCode );
- if ( StringUtils.isNotEmpty( err.getOutput() ) )
- {
- msg.append( " - " ).append( err.getOutput() );
- }
- msg.append( '\n' );
- msg.append( "Command line was: " ).append( cmd ).append( '\n'
).append( '\n' );
-
- throw new MojoExecutionException( msg.toString() );
- }
-
- if ( StringUtils.isNotEmpty( output ) )
- {
- //getLog().info( output );
- for ( String outputLine : output.split( "\n" ) )
- {
- getLog().info( outputLine );
- }
- }
- }
- catch ( CommandLineException e )
- {
- throw new MojoExecutionException( "Unable to execute jlink
command: " + e.getMessage(), e );
- }
-
+ return new JLinkExecutor( getToolchain().orElse( null ), getLog() );
}
- protected Toolchain getToolchain()
+ protected Optional<Toolchain> getToolchain()
{
Toolchain tc = null;
@@ -207,12 +73,12 @@ public abstract class AbstractJLinkMojo
// Maven 3.3.1 has plugin execution scoped Toolchain Support
try
{
- Method getToolchainsMethod =
toolchainManager.getClass().getMethod( "getToolchains", MavenSession.class,
-
String.class, Map.class );
+ Method getToolchainsMethod =
toolchainManager.getClass().getMethod( "getToolchains",
+ MavenSession.class, String.class, Map.class );
@SuppressWarnings( "unchecked" )
- List<Toolchain> tcs =
- (List<Toolchain>) getToolchainsMethod.invoke(
toolchainManager, session, "jdk", jdkToolchain );
+ List<Toolchain> tcs = (List<Toolchain>)
getToolchainsMethod.invoke( toolchainManager, getSession(),
+ "jdk", jdkToolchain );
if ( tcs != null && tcs.size() > 0 )
{
@@ -236,10 +102,10 @@ public abstract class AbstractJLinkMojo
if ( tc == null )
{
// TODO: Check if we should make the type configurable?
- tc = toolchainManager.getToolchainFromBuildContext( "jdk", session
);
+ tc = toolchainManager.getToolchainFromBuildContext( "jdk",
getSession() );
}
- return tc;
+ return Optional.ofNullable( tc );
}
protected MavenProject getProject()
diff --git
a/src/main/java/org/apache/maven/plugins/jlink/AbstractJLinkToolchainExecutor.java
b/src/main/java/org/apache/maven/plugins/jlink/AbstractJLinkToolchainExecutor.java
new file mode 100644
index 0000000..a38a9c7
--- /dev/null
+++
b/src/main/java/org/apache/maven/plugins/jlink/AbstractJLinkToolchainExecutor.java
@@ -0,0 +1,204 @@
+package org.apache.maven.plugins.jlink;
+
+/*
+ * 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.
+ */
+
+import org.apache.commons.lang3.SystemUtils;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.shared.utils.cli.CommandLineException;
+import org.apache.maven.shared.utils.cli.CommandLineUtils;
+import org.apache.maven.shared.utils.cli.Commandline;
+import org.apache.maven.toolchain.Toolchain;
+import org.codehaus.plexus.util.StringUtils;
+
+import java.io.File;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Optional;
+
+abstract class AbstractJLinkToolchainExecutor extends AbstractJLinkExecutor
+{
+ private final Toolchain toolchain;
+
+ AbstractJLinkToolchainExecutor( Toolchain toolchain, Log log )
+ {
+ super( log );
+ this.toolchain = toolchain;
+ }
+
+ protected Optional<Toolchain> getToolchain()
+ {
+ return Optional.ofNullable( this.toolchain );
+ }
+
+ /**
+ * Execute JLink via toolchain.
+ *
+ * @return the exit code ({@code 0} on success).
+ */
+ @Override
+ public int executeJlink( List<String> jlinkArgs ) throws
MojoExecutionException
+ {
+ File jlinkExecutable = getJlinkExecutable();
+ getLog().info( "Toolchain in maven-jlink-plugin: jlink [ " +
jlinkExecutable + " ]" );
+
+ Commandline cmd = createJLinkCommandLine( jlinkArgs );
+ cmd.setExecutable( jlinkExecutable.getAbsolutePath() );
+
+ return executeCommand( cmd );
+ }
+
+ private File getJlinkExecutable()
+ {
+ return new File( getJLinkExecutable() );
+ }
+
+ @Override
+ public Optional<File> getJmodsFolder( /* nullable */ File sourceJdkModules
)
+ {
+ // Really Hacky...do we have a better solution to find the jmods
directory of the JDK?
+ File jLinkParent =
getJlinkExecutable().getParentFile().getParentFile();
+ File jmodsFolder;
+ if ( sourceJdkModules != null && sourceJdkModules.isDirectory() )
+ {
+ jmodsFolder = new File( sourceJdkModules, JMODS );
+ }
+ else
+ {
+ jmodsFolder = new File( jLinkParent, JMODS );
+ }
+
+ getLog().debug( " Parent: " + jLinkParent.getAbsolutePath() );
+ getLog().debug( " jmodsFolder: " + jmodsFolder.getAbsolutePath() );
+
+ return Optional.of( jmodsFolder );
+ }
+
+ private Commandline createJLinkCommandLine( List<String> jlinkArgs )
+ {
+ Commandline cmd = new Commandline();
+ jlinkArgs.forEach( arg -> cmd.createArg().setValue( arg ) );
+
+ return cmd;
+ }
+
+ private String getJLinkExecutable()
+ {
+ Optional<Toolchain> toolchain = getToolchain();
+
+ if ( !toolchain.isPresent() )
+ {
+ getLog().error( "Either JDK9+ or a toolchain "
+ + "pointing to a JDK9+ containing a jlink binary is
required." );
+ getLog().info( "See
https://maven.apache.org/guides/mini/guide-using-toolchains.html "
+ + "for mor information." );
+ throw new IllegalStateException( "Running on JDK8 and no toolchain
found." );
+ }
+
+ String jLinkExecutable = toolchain.orElseThrow(
NoSuchElementException::new ).findTool( "jlink" );
+
+ if ( StringUtils.isEmpty( jLinkExecutable ) )
+ {
+ throw new IllegalStateException( "The jlink executable '"
+ + jLinkExecutable + "' doesn't exist or is not a file." );
+ }
+
+ // TODO: Check if there exist a more elegant way?
+ String jLinkCommand = "jlink" + ( SystemUtils.IS_OS_WINDOWS ? ".exe" :
"" );
+
+ File jLinkExe = new File( jLinkExecutable );
+
+ if ( jLinkExe.isDirectory() )
+ {
+ jLinkExe = new File( jLinkExe, jLinkCommand );
+ }
+
+ if ( SystemUtils.IS_OS_WINDOWS && jLinkExe.getName().indexOf( '.' ) <
0 )
+ {
+ jLinkExe = new File( jLinkExe.getPath() + ".exe" );
+ }
+
+ if ( !jLinkExe.isFile() )
+ {
+ throw new IllegalStateException( "The jlink executable '"
+ + jLinkExe + "' doesn't exist or is not a file." );
+ }
+ return jLinkExe.getAbsolutePath();
+ }
+
+ private int executeCommand( Commandline cmd )
+ throws MojoExecutionException
+ {
+ if ( getLog().isDebugEnabled() )
+ {
+ // no quoted arguments ???
+ getLog().debug( CommandLineUtils.toString( cmd.getCommandline()
).replaceAll( "'", "" ) );
+ }
+
+ CommandLineUtils.StringStreamConsumer err = new
CommandLineUtils.StringStreamConsumer();
+ CommandLineUtils.StringStreamConsumer out = new
CommandLineUtils.StringStreamConsumer();
+ try
+ {
+ int exitCode = CommandLineUtils.executeCommandLine( cmd, out, err
);
+
+ String output = ( StringUtils.isEmpty( out.getOutput() ) ? null :
'\n' + out.getOutput().trim() );
+
+ if ( exitCode != 0 )
+ {
+
+ if ( StringUtils.isNotEmpty( output ) )
+ {
+ // Reconsider to use WARN / ERROR ?
+ // getLog().error( output );
+ for ( String outputLine : output.split( "\n" ) )
+ {
+ getLog().error( outputLine );
+ }
+ }
+
+ StringBuilder msg = new StringBuilder( "\nExit code: " );
+ msg.append( exitCode );
+ if ( StringUtils.isNotEmpty( err.getOutput() ) )
+ {
+ msg.append( " - " ).append( err.getOutput() );
+ }
+ msg.append( '\n' );
+ msg.append( "Command line was: " ).append( cmd ).append( '\n'
).append( '\n' );
+
+ throw new MojoExecutionException( msg.toString() );
+ }
+
+ if ( StringUtils.isNotEmpty( output ) )
+ {
+ //getLog().info( output );
+ for ( String outputLine : output.split( "\n" ) )
+ {
+ getLog().info( outputLine );
+ }
+ }
+
+ return exitCode;
+ }
+ catch ( CommandLineException e )
+ {
+ throw new MojoExecutionException( "Unable to execute jlink
command: " + e.getMessage(), e );
+ }
+ }
+}
diff --git a/src/it/projects/MJLINK-40_includeLocales/verify.groovy
b/src/main/java/org/apache/maven/plugins/jlink/JLinkExecutor.java
similarity index 52%
copy from src/it/projects/MJLINK-40_includeLocales/verify.groovy
copy to src/main/java/org/apache/maven/plugins/jlink/JLinkExecutor.java
index 1887547..7482adb 100644
--- a/src/it/projects/MJLINK-40_includeLocales/verify.groovy
+++ b/src/main/java/org/apache/maven/plugins/jlink/JLinkExecutor.java
@@ -1,3 +1,5 @@
+package org.apache.maven.plugins.jlink;
+
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -17,38 +19,19 @@
* under the License.
*/
-import java.io.*;
-import java.util.*;
-import java.util.jar.*;
-import org.codehaus.plexus.util.*;
-
-boolean result = false;
+import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.toolchain.Toolchain;
-try
+/**
+ * JDK 8-only Jlink executor.
+ *
+ * <p>As JDK8 does not ship jlink, a toolchain is required.</p>
+ */
+class JLinkExecutor extends AbstractJLinkToolchainExecutor
{
- File target = new File( basedir, "target" );
- if ( !target.exists() || !target.isDirectory() )
- {
- System.err.println( "target file is missing or not a directory." );
- return false;
- }
- File jlinkArgs = new File( target, "jlinkArgs" );
- if ( !jlinkArgs.exists() || jlinkArgs.isDirectory() )
+ JLinkExecutor( Toolchain toolchain, Log log )
{
- System.err.println( "jlinkArgs file is missing or is a directory." );
- return false;
+ super( toolchain, log );
}
- def line = jlinkArgs.eachLine { line ->
- if (line.equals('en,ja,de,*-IN'))
- {
- result = true;
- }
- }
}
-catch( Throwable e )
-{
- e.printStackTrace();
-}
-
-return result;
diff --git a/src/main/java/org/apache/maven/plugins/jlink/JLinkMojo.java
b/src/main/java/org/apache/maven/plugins/jlink/JLinkMojo.java
index 14bebdc..3256565 100644
--- a/src/main/java/org/apache/maven/plugins/jlink/JLinkMojo.java
+++ b/src/main/java/org/apache/maven/plugins/jlink/JLinkMojo.java
@@ -21,7 +21,6 @@ package org.apache.maven.plugins.jlink;
import java.io.File;
import java.io.IOException;
-import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -29,6 +28,8 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.NoSuchElementException;
+import java.util.Optional;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.plugin.MojoExecutionException;
@@ -49,7 +50,6 @@ import
org.codehaus.plexus.languages.java.jpms.LocationManager;
import org.codehaus.plexus.languages.java.jpms.ResolvePathsRequest;
import org.codehaus.plexus.languages.java.jpms.ResolvePathsResult;
import org.codehaus.plexus.util.FileUtils;
-import org.codehaus.plexus.util.cli.Commandline;
/**
* The JLink goal is intended to create a Java Run Time Image file based on
@@ -64,8 +64,6 @@ import org.codehaus.plexus.util.cli.Commandline;
public class JLinkMojo
extends AbstractJLinkMojo
{
- private static final String JMODS = "jmods";
-
@Component
private LocationManager locationManager;
@@ -274,41 +272,20 @@ public class JLinkMojo
@Parameter( defaultValue = "${project.build.finalName}", readonly = true )
private String finalName;
- public void execute()
- throws MojoExecutionException, MojoFailureException
+ @Override
+ public void execute() throws MojoExecutionException, MojoFailureException
{
-
- String jLinkExec = getExecutable();
-
- getLog().info( "Toolchain in maven-jlink-plugin: jlink [ " + jLinkExec
+ " ]" );
-
- // TODO: Find a more better and cleaner way?
- File jLinkExecuteable = new File( jLinkExec );
-
- // Really Hacky...do we have a better solution to find the jmods
directory of the JDK?
- File jLinkParent = jLinkExecuteable.getParentFile().getParentFile();
- File jmodsFolder;
- if ( sourceJdkModules != null && sourceJdkModules.isDirectory() )
- {
- jmodsFolder = new File ( sourceJdkModules, JMODS );
- }
- else
- {
- jmodsFolder = new File( jLinkParent, JMODS );
- }
-
- getLog().debug( " Parent: " + jLinkParent.getAbsolutePath() );
- getLog().debug( " jmodsFolder: " + jmodsFolder.getAbsolutePath() );
-
failIfParametersAreNotInTheirValidValueRanges();
ifOutputDirectoryExistsDelteIt();
+ JLinkExecutor jLinkExec = getExecutor();
Collection<String> modulesToAdd = new ArrayList<>();
if ( addModules != null )
{
modulesToAdd.addAll( addModules );
}
+ jLinkExec.addAllModules( modulesToAdd );
Collection<String> pathsOfModules = new ArrayList<>();
if ( modulePaths != null )
@@ -326,27 +303,28 @@ public class JLinkMojo
}
// The jmods directory of the JDK
- pathsOfModules.add( jmodsFolder.getAbsolutePath() );
+ jLinkExec.getJmodsFolder( this.sourceJdkModules ).ifPresent(
+ jmodsFolder -> pathsOfModules.add(
jmodsFolder.getAbsolutePath() )
+ );
+ jLinkExec.addAllModulePaths( pathsOfModules );
+
+ List<String> jlinkArgs = createJlinkArgs( pathsOfModules, modulesToAdd
);
- Commandline cmd;
try
{
- cmd = createJLinkCommandLine( pathsOfModules, modulesToAdd );
+ jLinkExec.executeJlink( jlinkArgs );
}
- catch ( IOException e )
+ catch ( IllegalStateException e )
{
- throw new MojoExecutionException( e.getMessage() );
+ throw new MojoFailureException( "Unable to find jlink command: " +
e.getMessage(), e );
}
- cmd.setExecutable( jLinkExec );
-
- executeCommand( cmd, outputDirectoryImage );
File createZipArchiveFromImage = createZipArchiveFromImage(
buildDirectory, outputDirectoryImage );
if ( projectHasAlreadySetAnArtifact() )
{
throw new MojoExecutionException( "You have to use a classifier "
- + "to attach supplemental artifacts to the project instead of
replacing them." );
+ + "to attach supplemental artifacts to the project
instead of replacing them." );
}
getProject().getArtifact().setFile( createZipArchiveFromImage );
@@ -379,10 +357,12 @@ public class JLinkMojo
ResolvePathsRequest<File> request = ResolvePathsRequest.ofFiles(
dependencyArtifacts );
- Toolchain toolchain = getToolchain();
- if ( toolchain != null && toolchain instanceof
DefaultJavaToolChain )
+ Optional<Toolchain> toolchain = getToolchain();
+ if ( toolchain.isPresent()
+ && toolchain.orElseThrow( NoSuchElementException::new )
instanceof DefaultJavaToolChain )
{
- request.setJdkHome( new File( ( (DefaultJavaToolChain)
toolchain ).getJavaHome() ) );
+ Toolchain toolcahin1 = toolchain.orElseThrow(
NoSuchElementException::new );
+ request.setJdkHome( new File( ( (DefaultJavaToolChain)
toolcahin1 ).getJavaHome() ) );
}
ResolvePathsResult<File> resolvePathsResult =
locationManager.resolvePaths( request );
@@ -443,19 +423,9 @@ public class JLinkMojo
return modulepathElements;
}
- private String getExecutable()
- throws MojoFailureException
+ private JLinkExecutor getExecutor()
{
- String jLinkExec;
- try
- {
- jLinkExec = getJLinkExecutable();
- }
- catch ( IOException e )
- {
- throw new MojoFailureException( "Unable to find jlink command: " +
e.getMessage(), e );
- }
- return jLinkExec;
+ return getJlinkExecutor();
}
private boolean projectHasAlreadySetAnArtifact()
@@ -510,7 +480,7 @@ public class JLinkMojo
if ( endian != null && ( !"big".equals( endian ) && !"little".equals(
endian ) ) )
{
String message = "The given endian parameter " + endian
- + " does not contain one of the following values: 'little' or
'big'.";
+ + " does not contain one of the following values: 'little'
or 'big'.";
getLog().error( message );
throw new MojoFailureException( message );
}
@@ -537,130 +507,116 @@ public class JLinkMojo
}
}
- private Commandline createJLinkCommandLine( Collection<String>
pathsOfModules, Collection<String> modulesToAdd )
- throws IOException
+ private List<String> createJlinkArgs( Collection<String> pathsOfModules,
+ Collection<String> modulesToAdd )
{
- File file = new File( outputDirectoryImage.getParentFile(),
"jlinkArgs" );
- if ( !getLog().isDebugEnabled() )
- {
- file.deleteOnExit();
- }
- file.getParentFile().mkdirs();
- file.createNewFile();
-
- PrintStream argsFile = new PrintStream( file );
+ List<String> jlinkArgs = new ArrayList<>();
if ( stripDebug )
{
- argsFile.println( "--strip-debug" );
+ jlinkArgs.add( "--strip-debug" );
}
if ( bindServices )
{
- argsFile.println( "--bind-services" );
+ jlinkArgs.add( "--bind-services" );
}
if ( endian != null )
{
- argsFile.println( "--endian" );
- argsFile.println( endian );
+ jlinkArgs.add( "--endian" );
+ jlinkArgs.add( endian );
}
if ( ignoreSigningInformation )
{
- argsFile.println( "--ignore-signing-information" );
+ jlinkArgs.add( "--ignore-signing-information" );
}
if ( compress != null )
{
- argsFile.println( "--compress" );
- argsFile.println( compress );
+ jlinkArgs.add( "--compress" );
+ jlinkArgs.add( compress + "" );
}
if ( launcher != null )
{
- argsFile.println( "--launcher" );
- argsFile.println( launcher );
+ jlinkArgs.add( "--launcher" );
+ jlinkArgs.add( launcher );
}
if ( disablePlugin != null )
{
- argsFile.println( "--disable-plugin" );
- argsFile.append( '"' ).append( disablePlugin ).println( '"' );
+ jlinkArgs.add( "--disable-plugin" );
+ jlinkArgs.add( disablePlugin );
}
if ( pathsOfModules != null )
{
// @formatter:off
- argsFile.println( "--module-path" );
- argsFile.append( '"' )
- .append( getPlatformDependSeparateList( pathsOfModules )
- .replace( "\\", "\\\\" ) ).println( '"' );
+ jlinkArgs.add( "--module-path" );
+ jlinkArgs.add( getPlatformDependSeparateList( pathsOfModules
).replace( "\\", "\\\\" ) );
// @formatter:off
}
if ( noHeaderFiles )
{
- argsFile.println( "--no-header-files" );
+ jlinkArgs.add( "--no-header-files" );
}
if ( noManPages )
{
- argsFile.println( "--no-man-pages" );
+ jlinkArgs.add( "--no-man-pages" );
}
if ( hasSuggestProviders() )
{
- argsFile.println( "--suggest-providers" );
+ jlinkArgs.add( "--suggest-providers" );
String sb = getCommaSeparatedList( suggestProviders );
- argsFile.println( sb );
+ jlinkArgs.add( sb );
}
if ( hasLimitModules() )
{
- argsFile.println( "--limit-modules" );
+ jlinkArgs.add( "--limit-modules" );
String sb = getCommaSeparatedList( limitModules );
- argsFile.println( sb );
+ jlinkArgs.add( sb );
}
if ( !modulesToAdd.isEmpty() )
{
- argsFile.println( "--add-modules" );
+ jlinkArgs.add( "--add-modules" );
// This must be name of the module and *NOT* the name of the
// file! Can we somehow pre check this information to fail early?
String sb = getCommaSeparatedList( modulesToAdd );
- argsFile.append( '"' ).append( sb.replace( "\\", "\\\\" )
).println( '"' );
+ jlinkArgs.add( sb.replace( "\\", "\\\\" ) );
}
if ( hasIncludeLocales() )
{
- argsFile.println( "--add-modules" );
- argsFile.println( "jdk.localedata" );
- argsFile.println( "--include-locales" );
+ jlinkArgs.add( "--add-modules" );
+ jlinkArgs.add( "jdk.localedata" );
+ jlinkArgs.add( "--include-locales" );
String sb = getCommaSeparatedList( includeLocales );
- argsFile.println( sb );
+ jlinkArgs.add( sb );
}
if ( pluginModulePath != null )
{
- argsFile.println( "--plugin-module-path" );
+ jlinkArgs.add( "--plugin-module-path" );
StringBuilder sb =
convertSeparatedModulePathToPlatformSeparatedModulePath( pluginModulePath );
- argsFile.append( '"' ).append( sb.toString().replace( "\\", "\\\\"
) ).println( '"' );
+ jlinkArgs.add( sb.toString().replace( "\\", "\\\\" ) );
}
if ( buildDirectory != null )
{
- argsFile.println( "--output" );
- argsFile.println( outputDirectoryImage );
+ jlinkArgs.add( "--output" );
+ jlinkArgs.add( outputDirectoryImage.getAbsolutePath() );
}
if ( verbose )
{
- argsFile.println( "--verbose" );
+ jlinkArgs.add( "--verbose" );
}
- argsFile.close();
-
- Commandline cmd = new Commandline();
- cmd.createArg().setValue( '@' + file.getAbsolutePath() );
- return cmd;
+ return Collections.unmodifiableList( jlinkArgs );
}
private boolean hasIncludeLocales()
diff --git a/src/main/java9/org/apache/maven/plugins/jlink/JLinkExecutor.java
b/src/main/java9/org/apache/maven/plugins/jlink/JLinkExecutor.java
new file mode 100644
index 0000000..d562816
--- /dev/null
+++ b/src/main/java9/org/apache/maven/plugins/jlink/JLinkExecutor.java
@@ -0,0 +1,143 @@
+/*
+ * 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.jlink;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.toolchain.Toolchain;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.List;
+import java.util.Optional;
+import java.util.spi.ToolProvider;
+
+/**
+ * JDK9+ executor for jlink.
+ *
+ * <p>This implementation uses the JDK9+ Toolprovider SPI to find and execute
jlink.
+ * This way, no fork needs to be created.</p>
+ */
+class JLinkExecutor extends AbstractJLinkToolchainExecutor
+{
+ private final ToolProvider toolProvider;
+
+ JLinkExecutor( Toolchain toolchain, Log log ) throws IOException
+ {
+ super( toolchain, log );
+ this.toolProvider = getJLinkExecutable();
+ }
+
+ protected final ToolProvider getJLinkExecutable()
+ {
+ return ToolProvider
+ .findFirst( "jlink" )
+ .orElseThrow( () -> new IllegalStateException( "No jlink tool
found." ) );
+ }
+
+ @Override
+ public int executeJlink( List<String> jlinkArgs ) throws
MojoExecutionException
+ {
+ if (getToolchain().isPresent())
+ {
+ return super.executeJlink( jlinkArgs );
+ }
+
+ if ( getLog().isDebugEnabled() )
+ {
+ // no quoted arguments ???
+ getLog().debug( this.toolProvider.name() + " " + jlinkArgs );
+ }
+
+ try ( ByteArrayOutputStream baosErr = new ByteArrayOutputStream();
+ PrintWriter err = new PrintWriter( baosErr );
+ ByteArrayOutputStream baosOut = new ByteArrayOutputStream();
+ PrintWriter out = new PrintWriter( baosOut ) )
+ {
+ int exitCode = this.toolProvider.run( out, err, jlinkArgs.toArray(
new String[0] ) );
+ out.flush();
+ err.flush();
+
+ String outAsString = baosOut.toString( "UTF-8" );
+ String output = ( StringUtils.isEmpty( outAsString ) ? null : '\n'
+ outAsString.trim() );
+
+ if ( exitCode != 0 )
+ {
+ if ( StringUtils.isNotEmpty( output ) )
+ {
+ // Reconsider to use WARN / ERROR ?
+ // getLog().error( output );
+ for ( String outputLine : output.split( "\n" ) )
+ {
+ getLog().error( outputLine );
+ }
+ }
+
+ StringBuilder msg = new StringBuilder( "\nExit code: " );
+ msg.append( exitCode );
+ String errAsString = baosErr.toString();
+ if ( StringUtils.isNotEmpty( errAsString ) )
+ {
+ msg.append( " - " ).append( errAsString );
+ }
+ msg.append( '\n' );
+ msg.append( "Command line was: " ).append(
this.toolProvider.name() ).append( ' ' ).append(
+ jlinkArgs ).append( '\n' ).append( '\n' );
+
+ throw new MojoExecutionException( msg.toString() );
+ }
+
+ if ( StringUtils.isNotEmpty( output ) )
+ {
+ //getLog().info( output );
+ for ( String outputLine : output.split( "\n" ) )
+ {
+ getLog().info( outputLine );
+ }
+ }
+
+ return exitCode;
+ }
+ catch ( IOException e )
+ {
+ throw new MojoExecutionException( "Unable to execute jlink
command: " + e.getMessage(), e );
+ }
+ }
+
+ @Override
+ public Optional<File> getJmodsFolder( /* nullable */ File sourceJdkModules
)
+ {
+ if ( getToolchain().isPresent())
+ {
+ return super.getJmodsFolder( sourceJdkModules );
+ }
+
+ if ( sourceJdkModules != null && sourceJdkModules.isDirectory() )
+ {
+ return Optional.of( new File( sourceJdkModules, JMODS ) );
+ }
+
+ // ToolProvider does not need jmods folder to be set.
+ return Optional.empty();
+ }
+}