 ------
  Configuration and Usage
 ------
  John Casey
 ------
  2 November 2006
 ------

~~ Licensed to the Apache Software Foundation (ASF) under one
~~ or more contributor license agreements.  See the NOTICE file
~~ distributed with this work for additional information
~~ regarding copyright ownership.  The ASF licenses this file
~~ to you under the Apache License, Version 2.0 (the
~~ "License"); you may not use this file except in compliance
~~ with the License.  You may obtain a copy of the License at
~~
~~   http://www.apache.org/licenses/LICENSE-2.0
~~
~~ Unless required by applicable law or agreed to in writing,
~~ software distributed under the License is distributed on an
~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~~ KIND, either express or implied.  See the License for the
~~ specific language governing permissions and limitations
~~ under the License.

~~ NOTE: For help with the syntax of this file, see:
~~ http://maven.apache.org/doxia/references/apt-format.html

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>
        <version>${project.version}</version>
        <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}Resources}} section for more information), we can tell the
  Assembly Plugin to use it instead:
  
+---+
<project>
  [...]
  <build>
    [...]
    <plugins>
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>${project.version}</version>
        <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/index.html}examples section}} or the {{{plugin-info.html}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>
        <version>${project.version}</version>
        <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>
        <version>${project.version}</version>
        <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

~~
~~ 'single' and 'single-directory' should nearly always replace 'attached' and 'directory-inline'.
~~
~~** Creating Assemblies from Multiple Projects in a Multimodule Build
~~
~~  In certain cases, you may need to create several assembly archives from
~~  different points in a multimodule build. For this reason, two new assembly
~~  mojos have been introduced: <<<assembly:single>>>, and
~~  <<<assembly:directory-single>>>. These mojos will perform the usual tasks
~~  associated with creating assembly archives or directories, without running in
~~  a once-per-build mode. However, it's important to note that the use of the
~~  <<<\<moduleSets\>>>> section in the assembly descriptor may be limited in
~~  these cases, since the assembly mojo will not have access to the full list of
~~  projects in the current build. See the examples entry in the
~~  {{{#Resources}Resources}} section below for more information.

** 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}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>
        <version>${project.version}</version>
        <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}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}

  [[1]] For more information on writing your own assembly descriptor, read the 
        {{{assembly.html}Assembly Descriptor}}
        
  [[2]] For more information about the <<<maven-jar-plugin>>>, look
        {{{http://maven.apache.org/plugins/maven-jar-plugin/}here}}.
        
  [[3]] For more information on advanced <<<maven-assembly-plugin>>>
        configuration, see the {{{examples/index.html}examples}}.
  
  []


