[MJLINK-69] Require Java 11+ (#161)

* [MJLINK-69] Require Java 11+

* fix checkstyle
* update Jenkinsfile
diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
index 7fcb50b..6de5806 100644
--- a/.github/workflows/maven.yml
+++ b/.github/workflows/maven.yml
@@ -25,11 +25,11 @@
     strategy:
       matrix:
         os: [ ubuntu-latest, windows-latest, macOS-latest ]
-        java: [ 8, 11, 17 ]
-        dist: [ 'temurin', 'adopt-openj9' ]
+        java: [ 11, 17, 20 ]
+        dist: [ 'temurin', 'semeru' ]
         exclude:
         - os: macos-latest
-          dist: 'adopt-openj9'
+          dist: 'semeru'
 
       fail-fast: false
 
@@ -39,15 +39,6 @@
       - name: Checkout
         uses: actions/checkout@v3
 
-# https://github.com/actions/setup-java/blob/main/docs/advanced-usage.md#modifying-maven-toolchains
-      - name: Install Toolchain JDK
-        if: ${{ matrix.java == '8' }}
-        uses: actions/setup-java@v3
-        with:
-          distribution: ${{ matrix.dist }}
-          java-version: 11
-          cache: 'maven'
-
       - name: Set up JDK
         uses: actions/setup-java@v3
         with:
diff --git a/Jenkinsfile b/Jenkinsfile
index e9f05f7..b0e6d5e 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -17,4 +17,6 @@
  * under the License.
  */
 
-asfMavenTlpPlgnBuild()
+asfMavenTlpPlgnBuild([
+  'jdks': ['11', '17', '20']
+])
diff --git a/pom.xml b/pom.xml
index 80c333f..c2901ac 100644
--- a/pom.xml
+++ b/pom.xml
@@ -67,8 +67,9 @@
   <properties>
     <!-- required due to conflict with asm:asm:3.3.1 in Maven 3.1.0, see MNG-5499. -->
     <mavenVersion>3.1.1</mavenVersion>
-    <maven.compiler.source>1.8</maven.compiler.source>
-    <maven.compiler.target>1.8</maven.compiler.target>
+    <maven.compiler.release>11</maven.compiler.release>
+    <!-- needed for enforce-bytecode-version in maven-parent-pom. -->
+    <maven.compiler.target>${maven.compiler.release}</maven.compiler.target>
     <project.build.outputTimestamp>2020-12-21T12:52:28Z</project.build.outputTimestamp>
   </properties>
 
@@ -185,28 +186,6 @@
         </plugin>
       </plugins>
     </pluginManagement>
-    <plugins>
-      <plugin>
-        <artifactId>maven-enforcer-plugin</artifactId>
-        <version>3.3.0</version>
-        <executions>
-          <execution>
-            <id>enforce-bytecode-version</id>
-            <configuration>
-              <rules>
-                <enforceBytecodeVersion>
-                  <maxJdkVersion>${maven.compiler.target}</maxJdkVersion>
-                  <excludes>
-                    <exclude>org.ow2.asm:asm</exclude>
-                  </excludes>
-                </enforceBytecodeVersion>
-                <requireSameVersions />
-              </rules>
-            </configuration>
-          </execution>
-        </executions>
-      </plugin>
-    </plugins>
     <resources>
       <resource>
         <directory>src/main/filtered-resources</directory>
@@ -229,53 +208,6 @@
   </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
deleted file mode 100644
index d3282c7..0000000
--- a/src/it/projects/MJLINK-36_toolchainjdk8/invoker.properties
+++ /dev/null
@@ -1,20 +0,0 @@
-# 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
deleted file mode 100644
index f6a37cd..0000000
--- a/src/it/projects/MJLINK-36_toolchainjdk8/pom.xml
+++ /dev/null
@@ -1,95 +0,0 @@
-<?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_toolchainjdk8/verify.groovy b/src/it/projects/MJLINK-36_toolchainjdk8/verify.groovy
deleted file mode 100644
index d2a215e..0000000
--- a/src/it/projects/MJLINK-36_toolchainjdk8/verify.groovy
+++ /dev/null
@@ -1,32 +0,0 @@
-
-/*
- * 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 java.io.*
-import java.util.*
-import java.util.jar.*
-import org.codehaus.plexus.util.*
-
-File target = new File( basedir, "target" )
-assert target.isDirectory()
-
-File jarArtifact = new File( target, "mjlink36-toolchain-jdk8-1.0.0-SNAPSHOT.zip" )
-assert jarArtifact.isFile()
-
-// optional: check if it contains a launcher script
diff --git a/src/it/projects/MJLINK-36_toolchainjdk9/invoker.properties b/src/it/projects/MJLINK-36_toolchainjdk9/invoker.properties
deleted file mode 100644
index 271bf45..0000000
--- a/src/it/projects/MJLINK-36_toolchainjdk9/invoker.properties
+++ /dev/null
@@ -1,20 +0,0 @@
-# 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
deleted file mode 100644
index ab371a9..0000000
--- a/src/it/projects/MJLINK-36_toolchainjdk9/pom.xml
+++ /dev/null
@@ -1,95 +0,0 @@
-<?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-36_toolchainjdk9/verify.groovy b/src/it/projects/MJLINK-36_toolchainjdk9/verify.groovy
deleted file mode 100644
index 86433e4..0000000
--- a/src/it/projects/MJLINK-36_toolchainjdk9/verify.groovy
+++ /dev/null
@@ -1,32 +0,0 @@
-
-/*
- * 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 java.io.*
-import java.util.*
-import java.util.jar.*
-import org.codehaus.plexus.util.*
-
-File target = new File( basedir, "target" )
-assert target.isDirectory()
-
-File jarArtifact = new File( target, "mjlink36-toolchain-jdk9-1.0.0-SNAPSHOT.zip" )
-assert jarArtifact.isFile()
-
-// optional: check if it contains a launcher script
diff --git a/src/main/java/org/apache/maven/plugins/jlink/JLinkExecutor.java b/src/main/java/org/apache/maven/plugins/jlink/JLinkExecutor.java
index 7482adb..9953b50 100644
--- a/src/main/java/org/apache/maven/plugins/jlink/JLinkExecutor.java
+++ b/src/main/java/org/apache/maven/plugins/jlink/JLinkExecutor.java
@@ -19,19 +19,124 @@
  * under the License.
  */
 
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.List;
+import java.util.Optional;
+import java.util.spi.ToolProvider;
+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;
 
 /**
- * JDK 8-only Jlink executor.
+ * JDK9+ executor for jlink.
  *
- * <p>As JDK8 does not ship jlink, a toolchain is required.</p>
+ * <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 )
     {
         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 ( StringWriter strErr = new StringWriter();
+              PrintWriter err = new PrintWriter( strErr );
+              StringWriter strOut = new StringWriter();
+              PrintWriter out = new PrintWriter( strOut ) )
+        {
+            int exitCode = this.toolProvider.run( out, err, jlinkArgs.toArray( new String[0] ) );
+            out.flush();
+            err.flush();
+
+            String outAsString = strOut.toString();
+            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 = strErr.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();
+    }
 }
diff --git a/src/main/java9/org/apache/maven/plugins/jlink/JLinkExecutor.java b/src/main/java9/org/apache/maven/plugins/jlink/JLinkExecutor.java
deleted file mode 100644
index 2b825ed..0000000
--- a/src/main/java9/org/apache/maven/plugins/jlink/JLinkExecutor.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * 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.io.StringWriter;
-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 ( StringWriter strErr = new StringWriter();
-              PrintWriter err = new PrintWriter( strErr );
-              StringWriter strOut = new StringWriter();
-              PrintWriter out = new PrintWriter( strOut ) )
-        {
-            int exitCode = this.toolProvider.run( out, err, jlinkArgs.toArray( new String[0] ) );
-            out.flush();
-            err.flush();
-
-            String outAsString = strOut.toString();
-            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 = strErr.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();
-    }
-}