Building a Maven Complex Release Artifact: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
No edit summary
Line 6: Line 6:


This article describes the procedure of configuring Maven to build one complex release artifact, containing multiple individual artifacts, possibly produced by multiple modules, as well as arbitrary files from the project, dependencies, and so on, or otherwise what is known to Maven as an [[Maven_assembly_Plugin#Assembly|assembly]].
This article describes the procedure of configuring Maven to build one complex release artifact, containing multiple individual artifacts, possibly produced by multiple modules, as well as arbitrary files from the project, dependencies, and so on, or otherwise what is known to Maven as an [[Maven_assembly_Plugin#Assembly|assembly]].
!!!Multi-Module Assembly
!!!Overview
The most intuitive approach when dealing with multi-module projects is to build the "final" assembly in the root module. However, this has several drawbacks, as indicated by [http://www.sonatype.com/books/mvnref-book/reference/assemblies-sect-best-practices.html].
!!Drawback One: Repeated Execution
If the assembly plug-in is specified in the top pom.xml file of a multi-module project, the plug-in will be executed for each module (including root) at the specified phase.
When executing, the module will try to resolve the specified descriptor ''relative to the module root'', so if we have the following declaration and layout:
{{{
<project>
  </build>
        <plugins>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <descriptors>
                        <descriptor>assembly.xml</descriptor>
                    </descriptors>
                </configuration>
                ...
            </plugin>
        </plugins>
    </build>
</project>
}}}
{{{
  .
  +-- pom.xml
  |
  +-- assembly.xml  (1)
  |
  +-- mod1
      |
      +-- pom.xml
      |
      +-- assembly.xml (2)
}}}
then the root module will create its assembly based on assembly.xml (1) and mod1 will create its assembly based on assembly.xml (2).
!!Drawback Two: Root Module Builds First
... so if the "final" assembly depends on the artifacts of the children modules, we'll get into a deadlock.
!!!Recommended Approach
Create a separated module called "distribution", dedicated to building the final assembly, and make it a dependent of all other modules. Assuming that the root module is 'maven-root', "other" modules are 'mod1', then the "distribution" pom.xml should look similar to (with its private assembly.xml file in the module root):
{{{
<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>assembly</name>
    <parent>
        <groupId>org.novaordis.playground</groupId>
        <artifactId>maven-root</artifactId>
        <version>1.0.0</version>
    </parent>
    <groupId>org.novaordis.playground</groupId>
    <artifactId>distribution</artifactId>
    <packaging>pom</packaging>
    <build>
        <plugins>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <configuration>
                    <descriptors>
                        <descriptor>assembly.xml</descriptor>
                    </descriptors>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>org.novaordis.playground</groupId>
            <artifactId>mod1</artifactId>
            <version>1.0.0</version>
        </dependency>
    </dependencies>
</project>
}}}
Don't forget to declare the "distribution" module in root.
!!!Example of a multi-module assembly file
{{{
}}}
__Referenced by:__\\
[{INSERT com.ecyrd.jspwiki.plugin.ReferringPagesPlugin WHERE max=20, maxwidth=50}]

Revision as of 16:04, 7 November 2016

Internal

Overview

This article describes the procedure of configuring Maven to build one complex release artifact, containing multiple individual artifacts, possibly produced by multiple modules, as well as arbitrary files from the project, dependencies, and so on, or otherwise what is known to Maven as an assembly.


!!!Multi-Module Assembly

!!!Overview

The most intuitive approach when dealing with multi-module projects is to build the "final" assembly in the root module. However, this has several drawbacks, as indicated by [1].


!!Drawback One: Repeated Execution

If the assembly plug-in is specified in the top pom.xml file of a multi-module project, the plug-in will be executed for each module (including root) at the specified phase.

When executing, the module will try to resolve the specified descriptor relative to the module root, so if we have the following declaration and layout:

{{{ <project>

  </build>
       <plugins>
           <plugin>
               <artifactId>maven-assembly-plugin</artifactId>
               <configuration>
                   <descriptors>
                       <descriptor>assembly.xml</descriptor>
                   </descriptors>
               </configuration>
               ...
           </plugin>
       </plugins>
   </build>

</project> }}}


 +-- assembly.xml   (1)
 

then the root module will create its assembly based on assembly.xml (1) and mod1 will create its assembly based on assembly.xml (2).

!!Drawback Two: Root Module Builds First

... so if the "final" assembly depends on the artifacts of the children modules, we'll get into a deadlock.

!!!Recommended Approach

Create a separated module called "distribution", dedicated to building the final assembly, and make it a dependent of all other modules. Assuming that the root module is 'maven-root', "other" modules are 'mod1', then the "distribution" pom.xml should look similar to (with its private assembly.xml file in the module root):

{{{ <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>assembly</name>
   <parent>
       <groupId>org.novaordis.playground</groupId>
       <artifactId>maven-root</artifactId>
       <version>1.0.0</version>
   </parent>
   <groupId>org.novaordis.playground</groupId>
   <artifactId>distribution</artifactId>
   <packaging>pom</packaging>
   <build>
       <plugins>
           <plugin>
               <artifactId>maven-assembly-plugin</artifactId>
               <configuration>
                   <descriptors>
                       <descriptor>assembly.xml</descriptor>
                   </descriptors>
               </configuration>
               <executions>
                   <execution>
                       <id>make-assembly</id>
                       <phase>package</phase>
                       <goals>
                           <goal>single</goal>
                       </goals>
                   </execution>
               </executions>
           </plugin>
       </plugins>
   </build>
   <dependencies>
       <dependency>
           <groupId>org.novaordis.playground</groupId>
           <artifactId>mod1</artifactId>
           <version>1.0.0</version>
       </dependency>
   </dependencies>

</project> }}}

Don't forget to declare the "distribution" module in root.

!!!Example of a multi-module assembly file

{{{ }}}

__Referenced by:__\\ [{INSERT com.ecyrd.jspwiki.plugin.ReferringPagesPlugin WHERE max=20, maxwidth=50}]