A programmer's tale

Sunday, January 21, 2007

Making with Maven2 machinery | Part2: making executable jar with multiple and nested dependencies

This is my second TIP for Maven2. This is about building jar and executable jar with multiple and nested dependencies in Maven2.
The plug-in needed for this purpose is maven assembly plug-in. Maven2 assembly plug-in home contains the definition and other information about assembly. It will be beneficial to have a look first.
I'm using three projects for this example.
1. swing-editor, 2. swing-ext and 3. java-ext.
1. swing-editor: It is our main/parent project. It has the following dependencies
a) junit3.8.1 b) swing-ext c) java-ext
junit3.8.1 is needed for the test purpose only. So the main dependencies can be shown as:

2. swing-ext: It contains some general Swing components and utilities for Java Swing. It depends on a) junit3.8.1 and b) java-ext. Hence the compiled jar entry look like:

3. java-ext: It mainly depends only on Apache commons-lang-2.1 except junit3.8.1 that is again only for testing. So the dependencies tree is:

Now if we see the whole picture of all dependencies, it will be like this:

We will see how to make the required jar using the pre-built assembly descriptor first. Then we will go for our own assembly descriptor and including the descriptor in the project POM file.

1) Using pre-build assembly descriptor:
POM file for "swing-editor":

<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.swing-editor</groupId>
<artifactId>swing-editor</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>My Company Swing Editor</name>
<url>http://www.mycompany.com</url>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.mycompany.java-ext</groupId>
<artifactId>java-ext</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.mycompany.swing-ext</groupId>
<artifactId>swing-ext</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.1</version>
<configuration>
<finalName>swing-editor</finalName>
</configuration>
</plugin>
</plugins>
</build>
</project>

Now you can make the jar by giving the following command:
mvn assembly:assembly -DdescriptorId=jar-with-dependencies

The pre-build assembly descriptors of Maven2 are here. If you see the "jar-with-dependencies.xml" you will find that it's descriptorId is "jar-with-dependencies". The final jar is built with the name "swing-editor-jar-with-dependencies.jar" i.e. Id appended after the value of "finalName" tag in our main project POM file. Now if you want to make the jar executable then you have to mention the main class file name in the main POM file. In that case the assembly section of our main POM will be changed like:

<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.1</version>
<configuration>
<descriptors>
<descriptor>assembly.xml</descriptor>
</descriptors>
<archive>
<manifest>
<mainClass>com.mycompany.editor.Main</mainClass>
<addClasspath>true</addClasspath>
</manifest>
</archive>
<finalName>swing-editor</finalName>
</configuration>
</plugin>

2) Using custom assembly descriptor:
Now we write our assembly descriptor file. My descriptor file "assembly.xml" is more or less the copy of default descriptor file
except the "id" tag value has been changed.

<assembly>
<id>all</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>target/classes</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
</fileSets>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<unpack>true</unpack>
<scope>runtime</scope>
</dependencySet>
</dependencySets>
</assembly>

The required command in this case is:
mvn assembly:assembly -Ddescriptor=assembly.xml

Look my descriptor file is in "swing-editor" directory which is the project directory also. If you want to keep the assembly descriptor file in other location, then you have to mention the full path:
mvn assembly:assembly -Ddescriptor=/assembly.xml
You can customised the assembly file so many ways. The full descriptor file format is here. Customised it as your need.

3) Including descriptor in our POM file:
If you want to include the assembly descriptor file in your POM, then you have to modify the configuration section of your POM file as:

<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.1</version>
<configuration>
<descriptors>
<descriptor>assembly.xml</descriptor>
</descriptors>
<archive>
<manifest>
<mainClass>com.mycompany.editor.Main</mainClass>
<addClasspath>true</addClasspath>
</manifest>
</archive>
<finalName>swing-editor</finalName>
</configuration>
</plugin>
In this case you just need to mention the "goal" in the command line:
mvn assembly:assembly

0 Comments:

Post a Comment

<< Home