Trouble getting started with maven assembly plugin

JStroop picture JStroop · Apr 19, 2011 · Viewed 12.2k times · Source

I'm sorry to sound ignorant here, but I'm new to Maven, and have been banging my head against something that I'm sure is quite simple.

The docs say:

[...] a project could produce a ZIP assembly which contains a project's JAR artifact in the root directory, the runtime dependencies in a lib/ directory, and a shell script to launch a stand-alone application.

which is exactly what I want to do! But I can't seem to make it happen.

My POM is as follows:

<project>
   <modelVersion>4.0.0</modelVersion>
   <groupId>com.anearalone</groupId>
   <artifactId>myapp</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <packaging>jar</packaging>
   [...]
   <build>
      <finalName>myapp</finalName>
      <plugins>
         <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-assembly-plugin</artifactId>
         <version>2.2.1</version>
         <executions>
            <execution>
               <id>make-assembly</id>
               <phase>package</phase>
               <goals>
                  <goal>single</goal>
               </goals>
               <configuration>
                  <descriptors>
                     <descriptor>src/main/assemble/dist.xml</descriptor>
                  </descriptors>
                  <archive>
                     <manifest>
                        <mainClass>com.anearalone.myapp.CLI</mainClass>
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>lib/</classpathPrefix>
                     </manifest>
                  </archive>
               </configuration>
            </execution>
         </executions>
      </plugin>
   </plugins>
</build>
[...]
</project>

and the referenced dist.xml looks like this:

<assembly>
   <id>dist</id>
   <formats>
      <format>zip</format>
   </formats>
   <files>
      <file>
         <outputDirectory>/</outputDirectory>
         <source>src/main/bin/arkify.sh</source>
         <fileMode>755</fileMode>
      </file>
   </files>
   <dependencySets>
      <dependencySet>
         <useProjectArtifact>false</useProjectArtifact>
          <includes>
             <include>*:jar</include>
          </includes>
          <outputDirectory>/lib</outputDirectory>
      </dependencySet>
      <dependencySet>
         <useProjectArtifact>true</useProjectArtifact>
         <includes>
            <include>com.anearalone:myapp:jar:0.0.1-SNAPSHOT</include>
         </includes>
         <outputDirectory>/</outputDirectory>
      </dependencySet>
   </dependencySets>
</assembly>

This achieves the layout I want in the zip file (though I'm quite sure I'm not getting there in the correct way) but I get two jars in target/ (one in the zip archive, the other in the root), and neither of them includes my mainClass entry in the resultant MANIFEST.MF.

If I change the project.packaging to "pom", which I thought might be correct, of course the extra jar (in the root of target/ goes away, but I get these warning:

[WARNING] Cannot include project artifact: com.anearalone:myapp:pom:0.0.1-SNAPSHOT; it doesn't have an associated file or directory.
[WARNING] The following patterns were never triggered in this artifact inclusion filter:
o  'com.anearalone:myapp'

... and indeed my artifact is not in the archive, and there are still no entries added to MANIFEST.MF.

Anyone have time to help out a beginner?

Answer

Romain Linsolas picture Romain Linsolas · Apr 19, 2011

If I understand your problem correctly, your ZIP is correctly created, but the my-app-0.0.1-SNAPSHOT contained in it (as well as the JAR directly located in target/ directory) does not include your main class in the MANIFEST.MF file?

In fact, the assembly plugin is not dedicated to execute such a task. This is the task of the JAR plugin, which provides a way to indicates, in the MANIFEST.MF the main class of your project. You simply must add this configuration in your current pom.xml:

<plugins>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    ...
    <configuration>
      <archive>
        <manifest>
          <addClasspath>true</addClasspath>
          <mainClass>my.app.MainClass</mainClass>
        </manifest>
      </archive>
    </configuration>
  </plugin>
</plugins>

Regarding your try to change the packaging of the project to a pom packaging: it was a bad idea ;) Indeed, the pom packaging is used for project without any other resources than the pom.xml itself. It is really useful for pom.xml that are defined as the parent of others projects, or to aggregate multiples modules.