How's that for a confusing section title? Let's try to set
up a scenario which would explain the idea of assembling assemblies.
Imagine you want to create an archive which itself contains some project
assemblies. Assume that you have a multi-module build and you want to
deploy an assembly which contains a set of related project assemblies.
In this section's example, we create a bundle of "buildable" project
directories for a set of projects that are commonly used together. For
simplicity, we’ll reuse the two built-in assembly descriptors discussed
above - project and
jar-with-dependencies. In this particular example, it
is assumed that each project creates the project
assembly in addition to its main JAR artifact. Assume
that every project in a multi-module build binds the
single goal to the package phase
and uses the project
descriptorRef. Every project in a multi-module will
inherit the configuration from a top-level pom.xml
whose pluginManagement element is shown in Example 8.2, “Configuring the project assembly in top-level POM”.
Example 8.2. Configuring the project assembly in top-level POM
<project>
...
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-2</version>
<executions>
<execution>
<id>create-project-bundle</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptorRefs>
<descriptorRef>project</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
...
</project>
Each project POM references the managed plugin configuration from Example 8.2, “Configuring the project assembly in top-level POM” using a minimal plugin declaration in its build section shown in Example 8.3, “Activating the Assembly Plugin Configuration in Child Projects”.
Example 8.3. Activating the Assembly Plugin Configuration in Child Projects
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
</plugin>
</plugins>
</build>
To produce the set of project assemblies, run mvn install from the top-level directory. You should see Maven installing artifacts with classifiers in your local repository.
$ mvn install
...
Installing ~/mvn-examples-1.0/assemblies/as-dependencies/project-parent/\
second-project/target/second-project-1.0-SNAPSHOT-project.tar.gz to
~/.m2/repository/org/sonatype/mavenbook/assemblies/second-project/1.0-SNAPSHOT/\
second-project-1.0-SNAPSHOT-project.tar.gz
...
Installing ~/mvn-examples-1.0/assemblies/as-dependencies/project-parent/\
second-project/target/second-project-1.0-SNAPSHOT-project.tar.bz2 to
~/.m2/repository/org/sonatype/mavenbook/assemblies/second-project/1.0-SNAPSHOT/\
second-project-1.0-SNAPSHOT-project.tar.bz2
...
Installing ~/mvn-examples-1.0/assemblies/as-dependencies/project-parent/\
second-project/target/second-project-1.0-SNAPSHOT-project.zip to
~/.m2/repository/org/sonatype/mavenbook/assemblies/second-project/1.0-SNAPSHOT/\\
second-project-1.0-SNAPSHOT-project.zip
...
When you run install, Maven will copy the each project's main artifact and each assembly to your local Maven repository. All of these artifacts are now available for reference as dependencies in other projects locally. If your ultimate goal is to create a bundle which includes assemblies from multiple project, you can do so by creating another project which will include other project's assemblies as dependencies. This bundling project (aptly named project-bundle) is responsible for creating the bundled assembly. The POM for the bundling project would resemble the XML document listed in Example 8.4, “POM for the Assembly Bundling Project”.
Example 8.4. POM for the Assembly Bundling 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> <groupId>org.sonatype.mavenbook.assemblies</groupId> <artifactId>project-bundle</artifactId> <version>1.0-SNAPSHOT</version> <packaging>pom</packaging> <name>Assemblies-as-Dependencies Example Project Bundle</name> <url>http://sonatype.com/book</url> <dependencies> <dependency> <groupId>org.sonatype.mavenbook.assemblies</groupId> <artifactId>first-project</artifactId> <version>1.0-SNAPSHOT</version> <classifier>project</classifier> <type>zip</type> </dependency> <dependency> <groupId>org.sonatype.mavenbook.assemblies</groupId> <artifactId>second-project</artifactId> <version>1.0-SNAPSHOT</version> <classifier>project</classifier> <type>zip</type> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-assembly-plugin</artifactId> <version>2.2-beta-2</version> <executions> <execution> <id>bundle-project-sources</id> <phase>package</phase> <goals> <goal>single</goal> </goals> <configuration> <descriptorRefs> <descriptorRef> jar-with-dependencies </descriptorRef> </descriptorRefs> </configuration> </execution> </executions> </plugin> </plugins> </build> </project>
This bundling project's POM references the two
assemblies from first-project and
second-project. Instead of referencing the main
artifact of each project, the bundling project's POM
specifies a classifier of project and a type of
zip. This tells Maven to resolve the
ZIP archive which was created by the
project assembly. Note that the bundling project
generates a jar-with-dependencies assembly.
jar-with-dependencies does not create a particularly
elegant bundle, it simply creates a JAR file with the
unpacked contents of all of the dependencies.
jar-with-dependencies is really just telling Maven to
take all of the dependencies, unpack them, and then create a single
archive which includes the output of the current project. In this
project, it has the effect of creating a single JAR
file that puts the two project assemblies from
first-project and second-project
side-by-side.
This example illustrates how the basic capabilities of the Maven
Assembly plugin can be combined without the need for a custom assembly
descriptor. It achieves the purpose of creating a single archive that
contains the project directories for multiple projects side-by-side.
This time, the jar-with-dependencies is just a
storage format, so we don’t need to specify a
Main-Class manifest attribute. To build the bundle,
we just build the project-bundle project
normally:
$ mvn package
...
[INFO] [assembly:single {execution: bundle-project-sources}]
[INFO] Processing DependencySet (output=)
[INFO] Building jar: ~/downloads/mvn-examples-1.0/assemblies/as-dependencies/\
project-bundle/target/project-bundle-1.0-SNAPSHOT-jar-with-dependencies.jar
To verify that the project-bundle assembly contains the unpacked contents of the assembly dependencies, run jar tf:
$ jar tf \
target/project-bundle-1.0-SNAPSHOT-jar-with-dependencies.jar
...
first-project-1.0-SNAPSHOT/pom.xml
first-project-1.0-SNAPSHOT/src/main/java/org/sonatype/mavenbook/App.java
first-project-1.0-SNAPSHOT/src/test/java/org/sonatype/mavenbook/AppTest.java
...
second-project-1.0-SNAPSHOT/pom.xml
second-project-1.0-SNAPSHOT/src/main/java/org/sonatype/mavenbook/App.java
second-project-1.0-SNAPSHOT/src/test/java/org/sonatype/mavenbook/AppTest.java
After reading this section, the title should make more sense. You've assembled assemblies from two projects into an assembly using a bundling project which has a dependency on each of the assemblies.
