I've been at this one for a couple of days, so decided to post this here for future reference. My aim is to create a jar file, with a sub directory called lib, and have all the 3rd party dependencies in there, e.g
project.jar
/lib/spring-beans-3.0.5.RELEASE.jar
/lib/logback.jar
/lib/commons-cli-1.1.jar
The project looks like :
adapter
core
ftp
web-service
At this stage, I'm putting demo code together for different sprints, so only wanted some jar files to run from the command line. Maven Assembly is the package designed to do this, so I read the Apache Maven Assembly information, and the Sonatype manual on assemblies, but the examples on both were mixed, and it wasn't clear to me how to do get this working.. All of the material here was all written using Maven Assembly 2.2.1.
I got some basic examples going quickly, but then got bogged down adding a custom assembly descriptor (see below).
The recommendation in both references is to add another module to the project, so it looks like :
adapter
core
ftp
web-service
distribution
Below is the example code I'm currently using to get this : it will be refined, and as it get's better, I'll edit this post.
Parent pom :
Once you move to a multimodule build, make sure you move the plug in information out of the parent pom.xml, and ensure it exists only in the new distribution module's pom.
<?xml version="1.0" encoding="UTF-8"?>
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<name>proj</name>
<groupId>com.proj.adapter</groupId>
<artifactId>project</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<description>
..
</description>
<modules>
<module>proj-core</module>
<module>proj-ftp</module>
<module>proj-ws</module>
<module>distribution</module>
</modules>
<properties>
....
<maven.assembly.version>2.2.1</maven.assembly.version>
<plexus.utils.version>1.1</plexus.utils.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>proj-core</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
..
</dependencies>
<build>
<pluginManagement>
..
</pluginManagement>
</build>
</project>
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<name>proj</name>
<groupId>com.proj.adapter</groupId>
<artifactId>project</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<description>
..
</description>
<modules>
<module>proj-core</module>
<module>proj-ftp</module>
<module>proj-ws</module>
<module>distribution</module>
</modules>
<properties>
....
<maven.assembly.version>2.2.1</maven.assembly.version>
<plexus.utils.version>1.1</plexus.utils.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>proj-core</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
..
</dependencies>
<build>
<pluginManagement>
..
</pluginManagement>
</build>
</project>
Distribution module pom.xml
The main items here are :
1. Identify the location of the custom assembly descriptor (shown in bold),
2. Bind the lifecycle in the executions tag. Some of the examples I saw had the configuration within the execution tag, but I never got this to work,
<?xml version="1.0" encoding="UTF-8"?> <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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.proj.adapter</groupId> <artifactId>adapterProject</artifactId> <version>1.0-SNAPSHOT</version> </parent> <artifactId>dist</artifactId> <packaging>pom</packaging> <name>Distribution</name> <dependencies> <dependency> <groupId>com.proj.adapter</groupId> <artifactId>adapterProject-core</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> <build> <finalName>adapterProject</finalName> <plugins> <plugin> <artifactId>maven-assembly-plugin</artifactId> <version>${maven.assembly.version}</version> <configuration> <descriptors> <descriptor>src/main/assembly/bin.xml</descriptor> </descriptors> </configuration> <executions> <execution> <id>distro-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
Custom assembly descriptor
This is just an xml file, referenced from the distribution modules pom.
For a good few hours this was the bit that got me, every attempt to build returned an error message that one file had to be included, and I couldn't see where I'd gone wrong on my dependencies. Eventually I cracked it, and have highlighted it here.
The examples I saw used
<includes> <include>*-ws</include> </includes>and other similar examples. Some didn't have the useAllReactorProjects included, but, eventually I got the distribution module to get the correct dependencies and find the file using the snippet below.
<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"> <id>bin</id> <formats> <format>dir</format> </formats> <moduleSets> <moduleSet> <useAllReactorProjects>true</useAllReactorProjects> <includes> <include>${project.groupId}:adapterProject-core</include> </includes> <binaries> <outputDirectory>/</outputDirectory> <unpack>false</unpack> <includeDependencies>true</includeDependencies> <dependencySets> <!-- create the location of the core jar--> <dependencySet> <includes> <include>${project.groupId}:adapterProject-core</include> </includes> <useTransitiveDependencies>false</useTransitiveDependencies> <outputDirectory>/</outputDirectory> <unpack>true</unpack> </dependencySet> <!-- create the lib directory for the supporting jars --> <dependencySet> <excludes> <exclude>${project.groupId}:adapterProject-core</exclude> </excludes> <useProjectArtifact>false</useProjectArtifact> <useTransitiveDependencies>false</useTransitiveDependencies> <outputDirectory>lib</outputDirectory> </dependencySet> </dependencySets> </binaries> </moduleSet> </moduleSets> </assembly>
Hope this helps someone else struggling with this.