Maven Assembly Plugin
Configuration and Usage
Introduction
This document is intended to provide instructions for using the maven-assembly-plugin. In order for this discussion to be useful, it's critical to cover two topics: configuration of the plugin - both inside the POM and, where possible, from the command line - and the different execution styles. For the sake of clarity, we'll cover configuration before execution.
Configuring the Assembly Plugin
Getting started with the Assembly Plugin is pretty simple. If you're using one of the prefabricated assembly descriptors, you just tell it which one; if you're using a custom assembly descriptor, you give it the path to the descriptor. Note that a single invocation of the Assembly Plugin can actually produce assemblies from multiple descriptors, allowing you maximum flexibility to customize the suite of binaries your project produces. When the assembly is created it will use the assemblyId as the artifact's classifier and will attach the created assembly to the project and will be uploaded into the repository on an install and deploy goal.
For example, imagine that our project produces a jar. If we want to create an assembly binary that includes our project's dependencies, we can take advantage of one of the Assembly Plugin's prefabricated descriptors, as follows:
<project> [...] <build> [...] <plugins> <plugin> <!-- NOTE: We don't need a groupId specification because the group is org.apache.maven.plugins ...which is assumed by default. --> <artifactId>maven-assembly-plugin</artifactId> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> [...] </project>
Note that the Assembly Plugin allows you to specify multiple descriptorRefs at once, to produce multiple types of assemblies in a single invocation.
Alternatively, we've created a custom assembly descriptor called src.xml in the src/main/assembly directory (see the Resources section for more information), we can tell the Assembly Plugin to use it instead:
<project> [...] <build> [...] <plugins> <plugin> <artifactId>maven-assembly-plugin</artifactId> <configuration> <descriptors> <descriptor>src/main/assembly/src.xml</descriptor> </descriptors> </configuration> [...] </project>
Again, note that we could specify multiple custom assembly descriptors here. Additionally, it's possible to specify a mixture of descriptors and descriptorRefs within the same configuration.
NOTE: Many other configuration options are available for the various mojos in the Assembly Plugin. For more information, see the examples section or the plugin parameter documentation.
Executing: Building an Assembly
Once you've configured the various descriptors and descriptorRefs for the assemblies you want the project to produce, it's time to determine how you want to build them.
Currently, there are two basic approaches to building assemblies: as a dedicated build action, or bound to a phase of the normal build lifecycle. Beyond this, it's also possible to have the Assembly Plugin simply create an assembly directory for any given descriptor or descriptorRef, instead of creating archives.
Building an Assembly as a Standalone Process
First, let's examine how we can build an assembly directly, as a process separate from the normal build lifecycle. In this case, assemblies won't be produced when the normal build is executed, only in special circumstances.
NOTE: Invoking the assembly and directory mojos will cause Maven to build the project using the normal lifecycle, up to the package phase. Because many assemblies will contain compiled classes and other binaries, it's reasonable to assume that the package phase will be required to ensure those binaries exist and have been tested. The main advantage of producing an assembly in this way is to avoid producing it as part of your normal build process. In some cases, you may only want to create an assembly periodically; these mojos provide two ways to accomplish that goal.
Normal Assemblies
You can build an assembly directly by executing:
mvn assembly:assembly
When this build completes, you should see a file in the target directory with a name similar to the following:
target/sample-1.0-SNAPSHOT-jar-with-dependencies.jar
Notice the artifact classifier, between the end of the version and the beginning of the file extension, jar-with-dependencies. This is the id of the assembly descriptor used to create this artifact.
Assembly Directories
You can construct an assembly directory directly from the command line by executing:
mvn assembly:directory
When completed, you should see a directory structure similar to this:
target |-- sample-1.0-SNAPSHOT-jar-with-dependencies | |-- META-INF | | |-- MANIFEST.MF | | `-- maven | | `-- org.sample | | `-- sample | | |-- pom.properties | | `-- pom.xml | |-- junit [...] | | `-- TestRunner.class | |-- junit3.8.1 | |-- org | | `-- sample | | `-- App.class | `-- stylesheet.css
Building an Assembly as Part of the Build Lifecycle
If you need to ensure that assemblies are produced whenever your project builds, or when a particular profile is activated (also useful for configuring other plugins during this special process), then the following two mojos are probably what you're looking for. The single and single-directory mojos are functional counterparts of the mojos discussed above, except that they are meant to bind into the default build lifecycle.
The assembly mojo forces a package phase build to execute, in order to guarantee the availability of project binaries. Unfortunately, this currently means that binding the assembly mojo to the default lifecycle will cause Maven to execute the build twice - once for the main process, and once again in a forked lifecycle which is spawned by the assembly mojo itself.
By contrast, the single mojo assumes that the build has already produced project binaries or whatever else it needs prior to building the assembly itself. Because they depend on correct binding to the lifecycle in order to gain access to the files required by your project assembly, the single and single-directory mojos require the user to have much more intimate knowledge of the build process.
Normal Assemblies
To bind the single mojo to a project's build lifecycle, you can add this configuration (assuming you're using the jar-with-dependencies prefabricated descriptor):
<project> [...] <build> [...] <plugins> <plugin> <artifactId>maven-assembly-plugin</artifactId> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> <executions> <execution> <id>make-assembly</id> <!-- this is used for inheritance merges --> <phase>package</phase> <!-- append to the packaging phase. --> <goals> <goal>single</goal> <!-- goals == mojos --> </goals> </execution> </executions> </plugin> [...] </project>
Then, to create a project assembly, simple execute the normal package phase from the default lifecycle:
mvn package
When this build completes, you should see a file in the target directory with a name similar to the following:
target/sample-1.0-SNAPSHOT-jar-with-dependencies.jar
Notice the artifact classifier, between the end of the version and the beginning of the file extension, jar-with-dependencies. This is the id of the assembly descriptor used to create this artifact.
Assembly Directories
If instead you want to bind the single-directory mojo to a project's build lifecycle - so you can construct a directory containing your assembly - you can add this configuration (assuming you're using the jar-with-dependencies prefabricated descriptor):
<project> [...] <build> [...] <plugins> <plugin> <artifactId>maven-assembly-plugin</artifactId> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> <executions> <execution> <id>make-assembly</id> <!-- this is used for inheritance merges --> <phase>package</phase> <!-- append to the packaging phase. --> <goals> <goal>single-directory</goal> <!-- goals == mojos --> </goals> </execution> </executions> </plugin> [...] </project>
Then, to create a project assembly, simple execute the normal package phase from the default lifecycle:
mvn package
When completed, you should see a directory structure similar to this:
target |-- sample-1.0-SNAPSHOT-jar-with-dependencies.dir | |-- META-INF | | |-- MANIFEST.MF | | `-- maven | | `-- org.sample | | `-- sample | | |-- pom.properties | | `-- pom.xml | |-- junit [...] | | `-- TestRunner.class | |-- junit3.8.1 | |-- org | | `-- sample | | `-- App.class | `-- stylesheet.css
Advanced Configuration
Creating an Executable Jar
As you've no doubt noticed, the Assembly Plugin can be a very useful way to create a self-contained binary artifact for your project, among many other things. However, once you've created this self-contained jar, you will probably want the ability to execute it using the -jar JVM switch.
To accommodate this, the Assembly Plugin supports configuration of an <archive> element which is identical to that supported by the maven-jar-plugin (see Resources). Using this configuration, it's easy to configure the Main-Class attribute of the jar manifest:
<project> [...] <build> [...] <plugins> <plugin> <artifactId>maven-assembly-plugin</artifactId> <configuration> [...] <archive> <manifest> <mainClass>org.sample.App</mainClass> </manifest> </archive> </configuration> [...] </plugin> [...] </project>
If we add this configuration to the single mojo example above and rebuild, we will see an entry like this in the META-INF/MANIFEST.MF file of the resulting jar:
[...] Main-Class: org.sample.App
For more information on advanced configuration for the Assembly Plugin, see the Resources section.
GOTCHA!
At this point, only the jar assembly format supports the <archive> configuration element. By definition, directory-based assembly mojos - assembly:directory, assembly:directory-inline, and assembly:directory-single - do not produce a jar-format archive, and therefore do not support the <archive> element.
Resources
- For more information on writing your own assembly descriptor, read the Assembly Descriptor
- For more information about the maven-jar-plugin, look here.
- For more information on advanced maven-assembly-plugin configuration, see the examples.