Continued maven-jlink-plugin
git-svn-id: https://svn.apache.org/repos/asf/maven/plugins/trunk@1763964 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/pom.xml b/pom.xml
index d2dc19c..0d1b72f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -61,6 +61,8 @@
<properties>
<mavenVersion>3.0</mavenVersion>
+ <maven.compiler.source>1.7</maven.compiler.source>
+ <maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
@@ -85,5 +87,59 @@
<artifactId>commons-lang</artifactId>
<version>2.4</version>
</dependency>
+<!-- <dependency> -->
+<!-- <groupId>org.mockito</groupId> -->
+<!-- <artifactId>mockito-core</artifactId> -->
+<!-- <version>1.9.5</version> -->
+<!-- <scope>test</scope> -->
+<!-- </dependency> -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.12</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>io.takari.maven.plugins</groupId>
+ <artifactId>takari-plugin-testing</artifactId>
+ <version>2.9.0</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency> <!-- used by takari-plugin-testing, don't give it compile scope! -->
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-compat</artifactId>
+ <version>${mavenVersion}</version>
+ <scope>test</scope>
+ </dependency>
+
</dependencies>
+
+ <build>
+ <resources>
+ <resource>
+ <directory>src/main/filtered-resources</directory>
+ <filtering>true</filtering>
+ </resource>
+ </resources>
+ </build>
+<!-- <build> -->
+<!-- <plugins> -->
+<!-- <plugin> -->
+<!-- <groupId>io.takari.maven.plugins</groupId> -->
+<!-- <artifactId>takari-lifecycle-plugin</artifactId> -->
+<!-- <version>1.12.1</version> -->
+<!-- <extensions>true</extensions> -->
+<!-- <executions> -->
+<!-- <execution> -->
+<!-- <id>testProperties</id> -->
+<!-- <phase>process-test-resources</phase> -->
+<!-- <goals> -->
+<!-- <goal>testProperties</goal> -->
+<!-- </goals> -->
+<!-- </execution> -->
+<!-- </executions> -->
+<!-- </plugin> -->
+<!-- </plugins> -->
+<!-- </build> -->
</project>
diff --git a/src/main/filtered-resources/META-INF/plexus/components.xml b/src/main/filtered-resources/META-INF/plexus/components.xml
new file mode 100644
index 0000000..b1554b1
--- /dev/null
+++ b/src/main/filtered-resources/META-INF/plexus/components.xml
@@ -0,0 +1,77 @@
+<?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.
+-->
+
+<component-set>
+ <components>
+ <!--
+ | JLINK
+ |-->
+ <component>
+ <role>org.apache.maven.artifact.handler.ArtifactHandler</role>
+ <role-hint>jlink</role-hint>
+ <implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation>
+ <configuration>
+ <type>jlink</type>
+ <includesDependencies>true</includesDependencies>
+ <language>java</language>
+ <addedToClasspath>false</addedToClasspath>
+ </configuration>
+ </component>
+
+ <!--
+ | Defining the phases with their appropriate plugins
+ ! and versions which will be executed during the 'default'
+ ! life cycle.
+ -->
+ <!--
+ | JLINK
+ |-->
+ <component>
+ <role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
+ <role-hint>jlink</role-hint>
+ <implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation>
+ <configuration>
+ <lifecycles>
+ <lifecycle>
+ <id>default</id>
+ <!-- START SNIPPET: jlink-lifecycle -->
+ <phases>
+ <process-resources>
+ org.apache.maven.plugins:maven-resources-plugin:3.0.1:resources
+ </process-resources>
+ <package>
+ org.apache.maven.plugins:maven-jlink-plugin:${project.version}:jlink
+ </package>
+ <install>
+ org.apache.maven.plugins:maven-install-plugin:2.5.2:install
+ </install>
+ <deploy>
+ org.apache.maven.plugins:maven-deploy-plugin:2.8.2:deploy
+ </deploy>
+ </phases>
+ <!-- END SNIPPET: jlink-lifecycle -->
+ </lifecycle>
+ </lifecycles>
+ </configuration>
+ </component>
+
+ </components>
+</component-set>
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 bda6813..4a90d1f 100644
--- a/src/main/java/org/apache/maven/plugins/jlink/AbstractJLinkMojo.java
+++ b/src/main/java/org/apache/maven/plugins/jlink/AbstractJLinkMojo.java
@@ -167,7 +167,7 @@
if ( StringUtils.isNotEmpty( output ) )
{
//Reconsider to use WARN / ERROR ?
- getLog().info( output );
+ getLog().error( output );
}
StringBuilder msg = new StringBuilder( "\nExit code: " );
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 27eb088..8369cb9 100644
--- a/src/main/java/org/apache/maven/plugins/jlink/JLinkMojo.java
+++ b/src/main/java/org/apache/maven/plugins/jlink/JLinkMojo.java
@@ -1,5 +1,24 @@
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 java.io.File;
/*
@@ -22,14 +41,18 @@
*/
import java.io.IOException;
+import java.util.ArrayList;
import java.util.List;
+import org.apache.commons.lang.SystemUtils;
+import org.apache.maven.model.Dependency;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
+import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.cli.Commandline;
@@ -58,7 +81,9 @@
// TODO: Think if ResultionScope is needed here? May be we need to reconsider package phase?
// May be it would be wise to put into PREPARE-PACKAGE and the generation of the final jimage in the package phase?
// Furthermore It could make sense so we can change the conf files if needed...
-@Mojo( name = "jlink", requiresDependencyResolution = ResolutionScope.COMPILE, defaultPhase = LifecyclePhase.PACKAGE )
+// CHECKSTYLE_OFF: LineLength
+@Mojo( name = "jlink", requiresDependencyResolution = ResolutionScope.COMPILE, defaultPhase = LifecyclePhase.PACKAGE, requiresProject = true )
+// CHECKSTYLE_ON: LineLength
public class JLinkMojo
extends AbstractJLinkMojo
{
@@ -75,10 +100,11 @@
private Integer compression;
/**
- * Define the modulepath for the <code>JLink</code> call. <code>--module-path <modulepath></code>
+ * Define the modulepath for the <code>JLink</code> call. <code>--module-path <modulepath></code> TODO: The
+ * default should be the jmods folder of the JDK...
*/
- @Parameter( required = true )
- private File modulePath;
+ @Parameter
+ private List<String> modulePaths;
/**
* Limit the univers of observable modules. <code>--limit-modules <mod>[,<mod>...]</code>
@@ -99,12 +125,11 @@
private File pluginModulePath;
/**
- * <code>--output <path></code>
+ * <code>--output <path></code>
* </p>
- * TODO: Think about the default value? I'm not sure if something different would
- * be better?
+ * TODO: Think about the default value? I'm not sure if something different would be better?
*/
- @Parameter( defaultValue = "${project.build.output}/link-result" )
+ @Parameter( defaultValue = "${project.build.directory}/link-result" )
private File outputDirectory;
/**
@@ -119,27 +144,98 @@
throws MojoExecutionException, MojoFailureException
{
- failIfParametersAreNotInTheirValidValueRanges();
-
- String jLinkExecutable;
+ String jLinkExec;
try
{
- jLinkExecutable = getJLinkExecutable();
+ jLinkExec = getJLinkExecutable();
}
catch ( IOException e )
{
throw new MojoFailureException( "Unable to find jlink command: " + e.getMessage(), e );
}
+ getLog().info( "Toolchain in maven-jlink-plugin: jlink [ " + jLinkExec + " ]" );
+
+ // TODO: Find a more better and cleaner way?
+ File jLinkExecuteable = new File( jLinkExec );
+
+ // Really Hacky...
+ File jLinkParent = jLinkExecuteable.getParentFile().getParentFile();
+ File jmodsFolder = new File( jLinkParent, "jmods" );
+
+ getLog().debug( " Parent: " + jLinkParent.getAbsolutePath() );
+ getLog().debug( " jmodsFolder: " + jmodsFolder.getAbsolutePath() );
+
+ failIfParametersAreNotInTheirValidValueRanges();
+
deleteOutputDirectoryIfItAlreadyExists();
+ List<MavenProject> sortedProjects = getSession().getProjectDependencyGraph().getSortedProjects();
+ for ( MavenProject mavenProject : sortedProjects )
+ {
+ getLog().info( "MavenProject: " + mavenProject.getBasedir() );
+ }
+
+ List<Dependency> dependencies = getSession().getCurrentProject().getDependencies();
+
+ List<MavenProject> modulesToAdd = new ArrayList<>();
+ for ( Dependency dependency : dependencies )
+ {
+ if ( "jmod".equals( dependency.getType() ) )
+ {
+ MavenProject mp = findDependencyInProjects( dependency );
+ // TODO: What about module name != artifactId which has been
+ // defined in module-info.java file!
+ modulesToAdd.add( mp );
+ }
+ }
+
+ if ( addModules == null )
+ {
+ addModules = new ArrayList<>();
+ }
+ for ( MavenProject mavenProject : modulesToAdd )
+ {
+ addModules.add( mavenProject.getArtifactId() );
+ }
+
+ if ( modulePaths == null )
+ {
+ modulePaths = new ArrayList<>();
+ }
+
+ // JDK mods folder
+ modulePaths.add( jmodsFolder.getAbsolutePath() );
+
+ for ( MavenProject mavenProject : modulesToAdd )
+ {
+ File output = new File( mavenProject.getBuild().getDirectory(), "jmods" );
+ modulePaths.add( output.getAbsolutePath() );
+ }
+
// Synopsis
// Usage: jlink <options> --module-path <modulepath> --add-modules <mods> --output <path>
Commandline cmd = createJLinkCommandLine();
- cmd.setExecutable( jLinkExecutable );
+ cmd.setExecutable( jLinkExec );
executeCommand( cmd, outputDirectory );
-
+
+ }
+
+ private MavenProject findDependencyInProjects( Dependency dep )
+ {
+ List<MavenProject> sortedProjects = getSession().getProjectDependencyGraph().getSortedProjects();
+ MavenProject result = null;
+ for ( MavenProject mavenProject : sortedProjects )
+ {
+ if ( dep.getGroupId().equals( mavenProject.getGroupId() )
+ && dep.getArtifactId().equals( mavenProject.getArtifactId() )
+ && dep.getVersion().equals( mavenProject.getVersion() ) )
+ {
+ result = mavenProject;
+ }
+ }
+ return result;
}
private void failIfParametersAreNotInTheirValidValueRanges()
@@ -152,6 +248,18 @@
getLog().error( message );
throw new MojoFailureException( message );
}
+
+ // CHECK if this assumption here is correct?
+ // if ( modulePaths != null && ( !modulePaths.isEmpty() ) )
+ // {
+ //
+ // // FIXME: Need to check if the given paths exists? and if they are
+ // // folders?
+ // // String message = "The given module-paths parameter " + modulePath.getAbsolutePath()
+ // // + " is not a directory or does not exist.";
+ // // getLog().error( message );
+ // // throw new MojoFailureException( message );
+ // }
}
private void deleteOutputDirectoryIfItAlreadyExists()
@@ -163,6 +271,7 @@
// otherwise JLink will fail with a message "Error: directory already exists: ..."
try
{
+ getLog().debug( "Deleting existing " + outputDirectory.getAbsolutePath() );
FileUtils.forceDelete( outputDirectory );
}
catch ( IOException e )
@@ -174,7 +283,7 @@
}
}
- private Commandline createJLinkCommandLine()
+ Commandline createJLinkCommandLine()
{
Commandline cmd = new Commandline();
@@ -189,11 +298,11 @@
cmd.createArg().setValue( compression.toString() );
}
- // CHECK if this assumption here is correct?
- if ( modulePath != null && modulePath.exists() && modulePath.isDirectory() )
+ if ( modulePaths != null )
{
cmd.createArg().setValue( "--module-path" );
- cmd.createArg().setFile( modulePath );
+ StringBuilder sb = getColonSeparateList( modulePaths );
+ cmd.createArg().setValue( sb.toString() );
}
if ( limitModules != null && !limitModules.isEmpty() )
@@ -219,6 +328,28 @@
return cmd;
}
+ private StringBuilder getColonSeparateList( List<String> modulePaths )
+ {
+ StringBuilder sb = new StringBuilder();
+ for ( String module : modulePaths )
+ {
+ if ( sb.length() > 0 )
+ {
+ // FIXME: Check this ?
+ if ( SystemUtils.IS_OS_WINDOWS )
+ {
+ sb.append( ';' );
+ }
+ else
+ {
+ sb.append( ':' );
+ }
+ }
+ sb.append( module );
+ }
+ return sb;
+ }
+
private StringBuilder getCommaSeparatedList( List<String> modules )
{
StringBuilder sb = new StringBuilder();