You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by kh...@apache.org on 2017/06/05 21:54:47 UTC

svn commit: r1797711 - in /maven/plugins/trunk/maven-jlink-plugin: ./ src/main/filtered-resources/META-INF/plexus/ src/main/java/org/apache/maven/plugins/jlink/

Author: khmarbaise
Date: Mon Jun  5 21:54:47 2017
New Revision: 1797711

URL: http://svn.apache.org/viewvc?rev=1797711&view=rev
Log:
o Removed resources plugin fomr life cycle definition cause
  we can't offer supplemental files only via jlink
o Usage of jar as well as jmod packaging for link.
o Improved code
o JLink plugin creates now a zip file of the resulting
  image.

Modified:
    maven/plugins/trunk/maven-jlink-plugin/pom.xml
    maven/plugins/trunk/maven-jlink-plugin/src/main/filtered-resources/META-INF/plexus/components.xml
    maven/plugins/trunk/maven-jlink-plugin/src/main/java/org/apache/maven/plugins/jlink/AbstractJLinkMojo.java
    maven/plugins/trunk/maven-jlink-plugin/src/main/java/org/apache/maven/plugins/jlink/JLinkMojo.java

Modified: maven/plugins/trunk/maven-jlink-plugin/pom.xml
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-jlink-plugin/pom.xml?rev=1797711&r1=1797710&r2=1797711&view=diff
==============================================================================
--- maven/plugins/trunk/maven-jlink-plugin/pom.xml (original)
+++ maven/plugins/trunk/maven-jlink-plugin/pom.xml Mon Jun  5 21:54:47 2017
@@ -83,16 +83,21 @@
       <version>${mavenVersion}</version>
     </dependency>
     <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-archiver</artifactId>
+      <version>3.1.1</version>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.plexus</groupId>
+      <artifactId>plexus-archiver</artifactId>
+      <version>3.4</version>
+    </dependency> 
+    
+    <dependency>
       <groupId>commons-lang</groupId>
       <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>

Modified: maven/plugins/trunk/maven-jlink-plugin/src/main/filtered-resources/META-INF/plexus/components.xml
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-jlink-plugin/src/main/filtered-resources/META-INF/plexus/components.xml?rev=1797711&r1=1797710&r2=1797711&view=diff
==============================================================================
--- maven/plugins/trunk/maven-jlink-plugin/src/main/filtered-resources/META-INF/plexus/components.xml (original)
+++ maven/plugins/trunk/maven-jlink-plugin/src/main/filtered-resources/META-INF/plexus/components.xml Mon Jun  5 21:54:47 2017
@@ -30,6 +30,8 @@
       <implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation>
       <configuration>
         <type>jlink</type>
+        <extension>zip</extension>
+        <!-- Need to check the following? -->
         <includesDependencies>true</includesDependencies>
         <language>java</language>
         <addedToClasspath>false</addedToClasspath>
@@ -54,12 +56,11 @@
             <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>
+              <!-- What should be installed?
+              JRE image in zip/tar format? -->
               <install>
                 org.apache.maven.plugins:maven-install-plugin:2.5.2:install
               </install>

Modified: maven/plugins/trunk/maven-jlink-plugin/src/main/java/org/apache/maven/plugins/jlink/AbstractJLinkMojo.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-jlink-plugin/src/main/java/org/apache/maven/plugins/jlink/AbstractJLinkMojo.java?rev=1797711&r1=1797710&r2=1797711&view=diff
==============================================================================
--- maven/plugins/trunk/maven-jlink-plugin/src/main/java/org/apache/maven/plugins/jlink/AbstractJLinkMojo.java (original)
+++ maven/plugins/trunk/maven-jlink-plugin/src/main/java/org/apache/maven/plugins/jlink/AbstractJLinkMojo.java Mon Jun  5 21:54:47 2017
@@ -42,20 +42,17 @@ import org.codehaus.plexus.util.cli.Comm
 import org.codehaus.plexus.util.cli.Commandline;
 
 /**
- * 
  * @author Karl Heinz Marbaise <a href="mailto:khmarbaise@apache.org">khmarbaise@apache.org</a>
- *
  */
 public abstract class AbstractJLinkMojo
     extends AbstractMojo
 {
     /**
      * <p>
-     * Specify the requirements for this jdk toolchain.
-     * This overrules the toolchain selected by the maven-toolchain-plugin.
+     * Specify the requirements for this jdk toolchain. This overrules the toolchain selected by the
+     * maven-toolchain-plugin.
      * </p>
      * <strong>note:</strong> requires at least Maven 3.3.1
-     * 
      */
     @Parameter
     private Map<String, String> jdkToolchain;
@@ -65,11 +62,12 @@ public abstract class AbstractJLinkMojo
 
     @Parameter( defaultValue = "${session}", readonly = true, required = true )
     private MavenSession session;
-    
+
     @Component
     private ToolchainManager toolchainManager;
-    
-    protected String getJLinkExecutable() throws IOException
+
+    protected String getJLinkExecutable()
+        throws IOException
     {
         Toolchain tc = getToolchain();
 
@@ -99,8 +97,7 @@ public abstract class AbstractJLinkMojo
 
             if ( !jLinkExe.isFile() )
             {
-                throw new IOException( "The jlink executable '" + jLinkExe
-                    + "' doesn't exist or is not a file." );
+                throw new IOException( "The jlink executable '" + jLinkExe + "' doesn't exist or is not a file." );
             }
             return jLinkExe.getAbsolutePath();
         }
@@ -110,7 +107,7 @@ public abstract class AbstractJLinkMojo
         // By default, System.getProperty( "java.home" ) = JRE_HOME and JRE_HOME
         // should be in the JDK_HOME
         // ----------------------------------------------------------------------
-        // For IBM's JDK 1.2 
+        // For IBM's JDK 1.2
         // Really ?
         if ( SystemUtils.IS_OS_AIX )
         {
@@ -159,8 +156,9 @@ public abstract class AbstractJLinkMojo
 
         return jLinkExe.getAbsolutePath();
     }
-    
-    protected void executeCommand ( Commandline cmd, File outputDirectory ) throws MojoExecutionException
+
+    protected void executeCommand( Commandline cmd, File outputDirectory )
+        throws MojoExecutionException
     {
         if ( getLog().isDebugEnabled() )
         {
@@ -180,7 +178,7 @@ public abstract class AbstractJLinkMojo
             {
                 if ( StringUtils.isNotEmpty( output ) )
                 {
-                    //Reconsider to use WARN / ERROR ?
+                    // Reconsider to use WARN / ERROR ?
                     getLog().error( output );
                 }
 
@@ -207,24 +205,22 @@ public abstract class AbstractJLinkMojo
         }
 
     }
-    
+
     private Toolchain getToolchain()
     {
         Toolchain tc = null;
-        
+
         if ( jdkToolchain != null )
         {
             // 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>) getToolchainsMethod.invoke( toolchainManager, session, "jdk", jdkToolchain );
 
                 if ( tcs != null && tcs.size() > 0 )
                 {
@@ -252,12 +248,12 @@ public abstract class AbstractJLinkMojo
                 // ignore
             }
         }
-        
+
         if ( tc == null )
         {
             tc = toolchainManager.getToolchainFromBuildContext( "jdk", session );
         }
-        
+
         return tc;
     }
 
@@ -271,5 +267,60 @@ public abstract class AbstractJLinkMojo
         return session;
     }
 
+    /**
+     * Returns the archive file to generate, based on an optional classifier.
+     *
+     * @param basedir the output directory
+     * @param finalName the name of the ear file
+     * @param classifier an optional classifier
+     * @return the file to generate
+     */
+    protected File getArchiveFile( File basedir, String finalName, String classifier, String archiveExt )
+    {
+        if ( basedir == null )
+        {
+            throw new IllegalArgumentException( "basedir is not allowed to be null" );
+        }
+        if ( finalName == null )
+        {
+            throw new IllegalArgumentException( "finalName is not allowed to be null" );
+        }
+        if ( archiveExt == null )
+        {
+            throw new IllegalArgumentException( "archiveExt is not allowed to be null" );
+        }
+
+        if ( finalName.isEmpty() )
+        {
+            throw new IllegalArgumentException( "finalName is not allowed to be empty." );
+        }
+        if ( archiveExt.isEmpty() )
+        {
+            throw new IllegalArgumentException( "archiveExt is not allowed to be empty." );
+        }
+
+        StringBuilder fileName = new StringBuilder( finalName );
+
+        if ( hasClassifier( classifier ) )
+        {
+            fileName.append( "-" ).append( classifier );
+        }
+
+        fileName.append( '.' );
+        fileName.append( archiveExt );
+
+        return new File( basedir, fileName.toString() );
+    }
+
+    protected boolean hasClassifier( String classifier )
+    {
+        boolean result = false;
+        if ( classifier != null && classifier.trim().length() > 0 )
+        {
+            result = true;
+        }
+
+        return result;
+    }
 
 }

Modified: maven/plugins/trunk/maven-jlink-plugin/src/main/java/org/apache/maven/plugins/jlink/JLinkMojo.java
URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-jlink-plugin/src/main/java/org/apache/maven/plugins/jlink/JLinkMojo.java?rev=1797711&r1=1797710&r2=1797711&view=diff
==============================================================================
--- maven/plugins/trunk/maven-jlink-plugin/src/main/java/org/apache/maven/plugins/jlink/JLinkMojo.java (original)
+++ maven/plugins/trunk/maven-jlink-plugin/src/main/java/org/apache/maven/plugins/jlink/JLinkMojo.java Mon Jun  5 21:54:47 2017
@@ -29,11 +29,17 @@ import org.apache.commons.lang.SystemUti
 import org.apache.maven.model.Dependency;
 import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.Component;
 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.apache.maven.project.MavenProjectHelper;
+import org.codehaus.plexus.archiver.Archiver;
+import org.codehaus.plexus.archiver.ArchiverException;
+import org.codehaus.plexus.archiver.manager.ArchiverManager;
+import org.codehaus.plexus.archiver.zip.ZipArchiver;
 import org.codehaus.plexus.util.FileUtils;
 import org.codehaus.plexus.util.cli.Commandline;
 
@@ -88,6 +94,12 @@ import org.codehaus.plexus.util.cli.Comm
 public class JLinkMojo
     extends AbstractJLinkMojo
 {
+    private static final String JMOD_PACKAGING = "jmod";
+
+    private static final String JMODS = "jmods";
+
+    private static final String JAR_PACKAGING = "jar";
+
     /**
      * <code>-G, --strip-debug</code> strip debug information.
      */
@@ -124,6 +136,9 @@ public class JLinkMojo
      */
     // TODO: is this a good final location?
     @Parameter( defaultValue = "${project.build.directory}/jlink" )
+    private File outputDirectoryImage;
+
+    @Parameter( defaultValue = "${project.build.directory}" )
     private File outputDirectory;
 
     /**
@@ -179,6 +194,30 @@ public class JLinkMojo
     @Parameter( defaultValue = "false" )
     private boolean verbose;
 
+    /**
+     * The JAR archiver needed for archiving the environments.
+     */
+    @Component( role = Archiver.class, hint = "zip" )
+    private ZipArchiver zipArchiver;
+
+    @Component
+    private ArchiverManager manager;
+
+    /**
+     * The kind of archive we should produce.
+     */
+    @Parameter( defaultValue = "zip", required = true )
+    private String archiveType;
+
+    @Component
+    private MavenProjectHelper projectHelper;
+
+    /**
+     * Name of the generated JAR.
+     */
+    @Parameter( defaultValue = "${project.build.finalName}", readonly = true )
+    private String finalName;
+
     public void execute()
         throws MojoExecutionException, MojoFailureException
     {
@@ -198,9 +237,9 @@ public class JLinkMojo
         // TODO: Find a more better and cleaner way?
         File jLinkExecuteable = new File( jLinkExec );
 
-        // Really Hacky...
+        // Really Hacky...do we have a better solution?
         File jLinkParent = jLinkExecuteable.getParentFile().getParentFile();
-        File jmodsFolder = new File( jLinkParent, "jmods" );
+        File jmodsFolder = new File( jLinkParent, JMODS );
 
         getLog().debug( " Parent: " + jLinkParent.getAbsolutePath() );
         getLog().debug( " jmodsFolder: " + jmodsFolder.getAbsolutePath() );
@@ -209,28 +248,80 @@ public class JLinkMojo
 
         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<>();
+        getLog().info( "The following dependencies will be linked into the runtime image:" );
         for ( Dependency dependency : dependencies )
         {
-            // Should we only take care of module which have packaging "jmod"
-            // what about other modules/packaging types like "jar" ?
-            if ( "jmod".equals( dependency.getType() ) )
+            // We will support "jmod" as well as "jar"
+            if ( JAR_PACKAGING.equals( dependency.getType() ) || JMOD_PACKAGING.equals( dependency.getType() ) )
             {
                 MavenProject mp = findDependencyInProjects( dependency );
+                getLog().info( " -> " + mp.getId() );
                 // TODO: What about module name != artifactId which has been
                 // defined in module-info.java file!
                 modulesToAdd.add( mp );
             }
         }
 
+        handleAddModules( modulesToAdd );
+
+        handleModulePath( jmodsFolder, modulesToAdd );
+
+        Commandline cmd;
+        try
+        {
+            cmd = createJLinkCommandLine();
+        }
+        catch ( IOException e )
+        {
+            throw new MojoExecutionException( e.getMessage() );
+        }
+        cmd.setExecutable( jLinkExec );
+
+        executeCommand( cmd, outputDirectoryImage );
+
+        File createZipArchiveFromImage = createZipArchiveFromImage( outputDirectory, outputDirectoryImage );
+
+        // Set main artifact.
+        getProject().getArtifact().setFile( createZipArchiveFromImage );
+        // artifact.setFile( createZipArchiveFromImage );
+        // getProject().setFile( createZipArchiveFromImage );
+        // packaging is something different than type..
+        // projectHelper.attachArtifact( getProject(), "image", "image", createZipArchiveFromImage );
+
+    }
+
+    private File createZipArchiveFromImage( File outputDirectory, File outputDirectoryImage )
+        throws MojoExecutionException
+    {
+        zipArchiver.addDirectory( outputDirectoryImage );
+
+        File resultArchive = getArchiveFile( outputDirectory, finalName, null, "zip" );
+
+        zipArchiver.setDestFile( resultArchive );
+        try
+        {
+            zipArchiver.createArchive();
+        }
+        catch ( ArchiverException e )
+        {
+            getLog().error( e.getMessage(), e );
+            throw new MojoExecutionException( e.getMessage(), e );
+        }
+        catch ( IOException e )
+        {
+            getLog().error( e.getMessage(), e );
+            throw new MojoExecutionException( e.getMessage(), e );
+        }
+
+        return resultArchive;
+
+    }
+
+    private void handleAddModules( List<MavenProject> modulesToAdd )
+    {
         if ( addModules == null )
         {
             addModules = new ArrayList<>();
@@ -238,38 +329,31 @@ public class JLinkMojo
 
         for ( MavenProject mavenProject : modulesToAdd )
         {
+            // TODO: Check if this is the correct way?
+            // This implies the artifactId is equal to moduleName.
             addModules.add( mavenProject.getArtifactId() );
         }
+    }
 
+    /**
+     * @param jmodsFolder The folder where to find the jmods of the JDK.
+     * @param modulesToAdd The modules to be added.
+     */
+    private void handleModulePath( File jmodsFolder, List<MavenProject> modulesToAdd )
+    {
         if ( modulePaths == null )
         {
             modulePaths = new ArrayList<>();
         }
 
-        // JDK mods folder
+        // The jmods directory of the JDK
         modulePaths.add( jmodsFolder.getAbsolutePath() );
 
         for ( MavenProject mavenProject : modulesToAdd )
         {
-            File output = new File( mavenProject.getBuild().getDirectory(), "jmods" );
+            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;
-        try
-        {
-            cmd = createJLinkCommandLine();
-        }
-        catch ( IOException e )
-        {
-            throw new MojoExecutionException( e.getMessage() );
-        }
-        cmd.setExecutable( jLinkExec );
-
-        executeCommand( cmd, outputDirectory );
-
     }
 
     private MavenProject findDependencyInProjects( Dependency dep )
@@ -315,28 +399,28 @@ public class JLinkMojo
     private void deleteOutputDirectoryIfItAlreadyExists()
         throws MojoExecutionException
     {
-        if ( outputDirectory.exists() )
+        if ( outputDirectoryImage.exists() )
         {
             // Delete the output folder of JLink before we start
             // otherwise JLink will fail with a message "Error: directory already exists: ..."
             try
             {
-                getLog().debug( "Deleting existing " + outputDirectory.getAbsolutePath() );
-                FileUtils.forceDelete( outputDirectory );
+                getLog().debug( "Deleting existing " + outputDirectoryImage.getAbsolutePath() );
+                FileUtils.forceDelete( outputDirectoryImage );
             }
             catch ( IOException e )
             {
                 getLog().error( "IOException", e );
-                throw new MojoExecutionException( "Failure during deletion of " + outputDirectory.getAbsolutePath()
+                throw new MojoExecutionException( "Failure during deletion of " + outputDirectoryImage.getAbsolutePath()
                     + " occured." );
             }
         }
     }
 
-    Commandline createJLinkCommandLine()
+    private Commandline createJLinkCommandLine()
         throws IOException
     {
-        File file = new File( outputDirectory.getParentFile(), "jlinkArgs" );
+        File file = new File( outputDirectoryImage.getParentFile(), "jlinkArgs" );
         if ( !getLog().isDebugEnabled() )
         {
             file.deleteOnExit();
@@ -388,23 +472,25 @@ public class JLinkMojo
             argsFile.println( "--no-man-pages" );
         }
 
-        if ( suggestProviders != null && !suggestProviders.isEmpty() )
+        if ( hasSuggestProviders() )
         {
             argsFile.println( "--suggest-providers" );
             StringBuilder sb = getCommaSeparatedList( suggestProviders );
             argsFile.println( sb.toString() );
         }
 
-        if ( limitModules != null && !limitModules.isEmpty() )
+        if ( hasLimitModules() )
         {
             argsFile.println( "--limit-modules" );
             StringBuilder sb = getCommaSeparatedList( limitModules );
             argsFile.println( sb.toString() );
         }
 
-        if ( addModules != null && !addModules.isEmpty() )
+        if ( hasModules() )
         {
             argsFile.println( "--add-modules" );
+            // This must be name of the module and *NOT* the name of the
+            // file!
             StringBuilder sb = getCommaSeparatedList( addModules );
             argsFile.println( sb.toString() );
         }
@@ -412,7 +498,7 @@ public class JLinkMojo
         if ( outputDirectory != null )
         {
             argsFile.println( "--output" );
-            argsFile.println( outputDirectory );
+            argsFile.println( outputDirectoryImage );
         }
 
         if ( verbose )
@@ -427,6 +513,21 @@ public class JLinkMojo
         return cmd;
     }
 
+    private boolean hasSuggestProviders()
+    {
+        return suggestProviders != null && !suggestProviders.isEmpty();
+    }
+
+    private boolean hasLimitModules()
+    {
+        return limitModules != null && !limitModules.isEmpty();
+    }
+
+    private boolean hasModules()
+    {
+        return addModules != null && !addModules.isEmpty();
+    }
+
     private String getColonSeparateList( List<String> modulePaths )
     {
         StringBuilder sb = new StringBuilder();