Ondra.Žižka.cz

Vidělo 55 lidí

How to create an application distribution package with Maven

There are several ways to prepare a whole application bundle with all it's dependencies, properly written MANIFEST.MF and all other necessary things.

Appassembler plugin

The best way I have found is the Appassembler plugin.

This creates a .jar file with flattened content of all dependencies (i.e. unzips all jars and re-zips into a single one – no jars inside jars):

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <mainClass>########   CHANGE THIS   ######</mainClass>
</properties>


  <plugins>
     <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-assembly-plugin</artifactId>
        <executions>
           <execution> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution>
        </executions>
        <configuration>
           <appendAssemblyId>false</appendAssemblyId>
           <descriptorRefs>
               <descriptorRef>jar-with-dependencies</descriptorRef>
           </descriptorRefs>
           <!--
           <descriptors>
              <descriptor>src/assembly/assembly.xml</descriptor>
           </descriptors>
           -->
           <archive>
              <manifest>
                 <mainClass>${mainClass}</mainClass>
                 <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
                 <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
              </manifest>
           </archive>
        </configuration>
     </plugin>
  </plugins>

This creates an application ready for zipping in target/appassembler/:

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>appassembler-maven-plugin</artifactId>
        <version>1.1-SNAPSHOT</version>
        <executions>
          <execution>
            <id>appassemble</id>
            <goals><goal>assemble</goal></goals>
            <phase>package</phase>
          </execution>
        </executions>
        <configuration>
          <programs>
            <program>
              <mainClass>${mainClass}</mainClass>
              <name>app</name>
            </program>
          </programs>
        </configuration>
      </plugin>
    </plugins>
  </build>

</project>

Don't forget to add necessary repository and set the latest plugin version.

<pluginManagement>
   <plugins>
      <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-assembly-plugin</artifactId>
         <version>2.2.1</version>
      </plugin>
   </plugins>
</pluginManagement>

<pluginRepositories>
  <pluginRepository>
    <id>codehaus</id>
    <name>Codehaus Release Repo</name>
    <url>http://repository.codehaus.org</url>
  </pluginRepository>
  <pluginRepository>
    <id>codehaus-snapshot</id>
    <name>Codehaus Snapshot Repo</name>
    <url>http://snapshots.repository.codehaus.org</url>
  </pluginRepository>
</pluginRepositories>

More advanced example at plugin's usage page.

Preparing the bits for manual packaging

This pom.xml copies the dependencies to the target/lib/ dir and creates the MANIFEST.MF file.

<project>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <mainClass>cz.dynawest.jtexy.sandbox.swing.SwingSandboxApp</mainClass>
  </properties>

  <build>
    <plugins>

      <!-- Jar - MANIFEST.MF options. -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <configuration>
          <archive>
            <manifest>
              <addClasspath>true</addClasspath>
              <mainClass>${mainClass}</mainClass>
              <classpathPrefix>lib/</classpathPrefix>
            </manifest>
          </archive>
        </configuration>
      </plugin>

      <!-- Dependencies to lib/ . -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <configuration>
          <outputDirectory>${project.build.directory}/lib</outputDirectory>
          <includeScope>runtime</includeScope>
        </configuration>
      </plugin>


    </plugins>
  </build>

  <profiles>
    <!-- "Create distribution zip" profile. -->
    <profile>
      <id>dist</id>
      <build>
        <plugins>

          <!-- dependency:copy-dependencies -->
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <executions>
              <execution>
                <id>dep-copy</id>
                <phase>package</phase>
                <goals> <goal>copy-dependencies</goal> </goals>
              </execution>
            </executions>
          </plugin>

          <!-- It's also a good idea to create SOURCES and JAVADOC .jar's. -->
          <plugin>
            <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-source-plugin</artifactId> <version>2.1.1</version>
            <executions> <execution> <id>attach-sources</id> <phase>verify</phase>  <goals>  <goal>jar-no-fork</goal> </goals> </execution> </executions>
          </plugin>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-javadoc-plugin</artifactId>  <version>2.6.1</version>
            <executions> <execution> <id>attach-javadoc</id> <phase>verify</phase>  <goals>  <goal>jar</goal> </goals> </execution> </executions>
          </plugin>

        </plugins>
      </build>
    </profile>

  </profiles>

</project>
0