To generate a zip file, packaging all required dependent libraries and newly generated jar
, using maven-assembly-plugin
(for more detail on plugin refer).
I will demonstrate generation of package using assembly descriptor file.
- Create a assembly descriptor file which is a xml file (for more details refer and format) as following. Create this file inside your project directory. One can keep this descriptor file any where inside given project directory. I have tried it by keeping this file at location
<Project dir>/src/main/assembly/test-app-assembly.xml
andproviding complete path to descriptor file inpom.xml
.
e.g
test-app-assembly.xml
<?xml version="1.0" encoding="UTF-8"?>
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<formats>
<format>zip</format>
</formats>
<files>
<file>
<outputDirectory>/</outputDirectory>
<source>target/test-app.jar</source>
</file>
</files>
<!-- use this section if you want to package dependencies -->
<dependencySets>
<dependencySet>
<outputDirectory>lib</outputDirectory>
<useStrictFiltering>true</useStrictFiltering>
<useProjectArtifact>false</useProjectArtifact>
<scope>runtime</scope>
</dependencySet>
</dependencySets>
</assembly>
- In above descriptor file, its assumed the current project
artifact
is generated before thisplugin
gets executed andmaven-assembly-plugin
configured to run ininstall
phase only. - refer lines inside
<files>....</files>
in above code. We are specifying include generatedartifact
from the current module inside packaging, which will be placed inside root/
directory of the package zip.Note:
by defaultmaven
generatesartifact
in following format<artifact name>-<version>.jar
(with assumption packaging mentioned asjar
). You need to make sure to specify constant file name using property<finalName>
inside yourpom.xml
e.g
Section of pom.xml
<build>
......
....
<finalName>test-app.jar</finalName>
.......
....
</build>
- Next refer lines inside
<dependencySets> .... </dependencySets>
. Here we are specifying copy alldependency jars
inside/lib
directory of the package zip. - Next refer below changes in
pom.xml
.
e.g.
Section of pom.xml
<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">
......
.........
<build>
<finalName>test-app</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>create-distribution</id>
<phase>install</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>src/main/assembly/test-app-assembly.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
................
................
</plugins>
</build>
</project>
- Refer line
8 - 25
in above code from samplepom.xml
. Here we are configuringmaven-assembly-plugin
to invokesingle
goal ininstall
phase by referringtest-app-assembly.xml
file (refer line20
). - When you run the build
mvn clean install
at the end you will see filetest-app.zip
is generated inside target folder. If you open the zip file you will findtest-app.jar
andlib
folder in it and if you go inside lib folder you will find all requireddependencies
of current project are copied inside thislib
folder.
Above steps demonstrates how to generate required single package as zip
with all required dependencies
in it. Now we will look at how to make given application as executable jar
(When I say executable jar, one can configure main
class of given application, so that JVM
can invoke the application directly without specifying which class
to invoke on command line. you can run application like <extracted location of zip>$ java -jar test-app.jar -classpath <location of each dependent jar file>
). But its not just sufficient to just specify only main class
, we also need to add required dependent jar
files in class path while running application from command prompt. If we can add those dependent jar locations inside jar itself then you don’t have to mention it at command line. Refer below code changes using
maven-jar-plugin
.
Section of pom.xml
<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">
......
.........
<build>
<finalName>test-app</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>create-distribution</id>
<phase>install</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>src/main/assembly/test-app-assembly.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.pp.test.Sample</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
- refer line having tag
<mainClass>
, here we are specifying which class havingmain
method. At line having tag<addClasspath>
we are specifying add all dependency jars into classpath. But as all the dependentjars
we have placed insidelib
folder as per above packaging configuration written in test-app-assembly.xml, while specifying class path we need to prefix jar file name withlib/
refer tag<classpathPrefix>
. This will result in generation ofMETA-INF/MANIFEST.MF
file refer sample below.
Sample META-INF/MANIFEST.MF
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: pandurang
Build-Jdk: 1.7.0_17
Main-Class: com.pp.test.Sample
Class-Path: lib/javapns-2.2.jar lib/junit-4.8.1.jar lib/commons-lang-2.6.jar lib/commons-io-2.4.jar lib/mail-1.4.5.jar lib/activation-1.1.jar lib/google-http-client-jackson2-1.13.1-beta.jar lib/j
ackson-core-2.0.5.jar lib/jcommander-1.30.jar lib/log4j-1.2.17.jar lib/slf4j-api-1.6.6.jar
- With this you will be able to generate complete zip file with an
executable
jar file in it. Which makes the deployment and execution of application very easy. For deployment you need to just ship this generatedtest-app.zip
file which is a complete package. To run your application you can extract the zip file and issue following command<extracted location of zip>$ java -jar test-app.jar</span>
. Note here whenjar
is generated all requireddependencies
are mentioned insideMANIFEST.MF
you don’t have to specify them here.