Including Module Sources

Introduction

It is common practice to create an assembly using the parent POM of a multimodule build. At times, you may want to ensure that this assembly also includes the source code from one or more of the modules in this build.

This example demonstrates how to include the project sources from a module in the project assembly, under the directory sources/<module-name>.

The Assembly Descriptor

First, let's write an assembly descriptor to create this assembly. For the sake of clarity, this descriptor will be as simple as possible, only demonstrating the features described by this example.

<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.2.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.2.0 http://maven.apache.org/xsd/assembly-2.2.0.xsd">
  <id>src</id>
  <formats>
    <format>dir</format>
  </formats>
  <includeBaseDirectory>false</includeBaseDirectory>
  <moduleSets>
    <moduleSet>
      <useAllReactorProjects>true</useAllReactorProjects>
      <includes>
        <include>org.test:child1</include>
      </includes>
      <sources>
        <includeModuleDirectory>false</includeModuleDirectory>
        <fileSets>
          <fileSet>
            <outputDirectory>sources/${module.artifactId}</outputDirectory>
            <excludes>
              <exclude>${project.build.directory}/**</exclude>
            </excludes>
          </fileSet>
        </fileSets>
      </sources>
    </moduleSet>
  </moduleSets>
</assembly>

This descriptor states that the assembly id should be src, that the output format is a directory, and that the contents of the assembly should not be contained within a directory named after the finalName of the top-level project.

Furthermore, it states that we wish to include the source files for the module with a groupId of org.test and an artifactId of child1. These sources should be contained within the directory structure sources/child1 for this module, since the outputDirectory expression will be interpolated on a module-by-module basis.

By default, the Assembly Plugin will add the sources under a folder named with the artifactId of each module; this can be disabled by setting includeModuleDirectory to false.

Note that the build directory (target by default) will be included, so it is explicitly excluded since this is a temporary storage for files produced during the build and it should not contain any project sources.

The POM

Now, let's review the POM configuration necessary to enable the building of this assembly via the assembly:single goal:

<?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/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.test</groupId>
  <artifactId>parent</artifactId>
  <version>1.0</version>

  <packaging>pom</packaging>

  <name>Parent</name>

  <modules>
    <module>child1</module>
    <module>child2</module>
    <module>child3</module>
  </modules>

  <build>
    <plugins>
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>3.7.0</version>
        <configuration>
          <descriptors>
            <descriptor>src/assembly/src.xml</descriptor>
          </descriptors>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

This POM simply directs the Assembly Plugin to use the src.xml assembly descriptor when executing.

Execute!

To build the assembly, we issue the following command:

mvn clean assembly:single

This will ensure that the output directory (normally, target), is removed before building the assembly directory.

Examining the Output

When the Maven execution completes, the following directory structure should be left:

target/parent-1.0-src/
`-- sources
    `-- child1
        |-- pom.xml
        `-- src
            |-- main
            |   `-- java
            |       `-- org
            |           `-- test
            |               `-- App.java
            `-- test
                `-- java
                    `-- org
                        `-- test
                            `-- AppTest.java