Maven – How to use Maven assembly plugin with multi module maven project

mavenmaven-assembly-pluginmaven-jar-plugin

I am new to maven and spent ~3 days in generating the zip file with assembly plugin refering to http://www.petrikainulainen.net/programming/tips-and-tricks/creating-a-runnable-binary-distribution-with-maven-assembly-plugin/ My project is multi module, so I also referred to Managing multi-module dependencies with Maven assembly plugin

Still I have several inefficiencies. Below is assembly.xml (which I inherited from 1st link)

 <assembly>
<id>bin</id>
<!-- Generates a zip package containing the needed files -->
<formats>
    <format>zip</format>
</formats>

<!-- Adds dependencies to zip package under lib directory -->
<dependencySets>
    <dependencySet>
        <!-- Project artifact is not copied under library directory since it is 
            added to the root directory of the zip package. -->
        <useProjectArtifact>false</useProjectArtifact>
        <outputDirectory>lib</outputDirectory>
        <unpack>false</unpack>

    </dependencySet>
</dependencySets>
<moduleSets>
    <moduleSet>

        <!-- Enable access to all projects in the current multimodule build! <useAllReactorProjects>true</useAllReactorProjects> -->

        <!-- Now, select which projects to include in this module-set. -->
        <includes>
            <include>com.XX:YY-main</include>
        </includes>

        <!--<binaries> <outputDirectory>YY-main/target</outputDirectory> <unpack>false</unpack> 
            </binaries> -->
    </moduleSet>
</moduleSets>
<fileSets>
    <!-- Adds startup scripts to the root directory of zip package. The startup 
        scripts are located to src/main/scripts directory as stated by Maven conventions. -->
    <fileSet>
        <directory>${project.build.scriptSourceDirectory}</directory>
        <outputDirectory>conf</outputDirectory>
        <includes>
            <include>*</include>
        </includes>
    </fileSet>
    <fileSet>
        <directory>${project.build.directory}</directory>
        <outputDirectory></outputDirectory>
        <includes>
            <include>log4j.properties</include>
        </includes>
    </fileSet>
    <!-- adds jar package to the root directory of zip package -->
    <fileSet>
        <directory>${project.build.directory}</directory>
        <outputDirectory></outputDirectory>
        <includes>
            <include>*with-dependencies.jar</include>
        </includes>
    </fileSet>
</fileSets>

Below is the pom.xml (primary or main)

 <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.4</version>
             <configuration>                    <descriptors>
              <descriptor>YY-main/src/main/assembly/assembly.xml</descriptor>   
         <!-- <descriptor>DummyAssembly.xml</descriptor> -->

                </descriptors>
            </configuration>
        </plugin>   

Questions:

1)Since assembly.xml is referred in primary pom, all submodules also get zipped. How can I specify only certain submodules to be zipped, while all others get ignored. I tried to move YY-main/src/main/assembly/assembly.xml from main pom to child/submodule pom and have dummyassembly.xml in main which does nothing. But that is not working (possibly because dummyassembly.xml is missing some required lines). tried few things, but nothing seem to work

2)Also in assembly.xml (dependencyset), it is copying all the libraries to "lib" folder. How can I avoid this. again I tried few things (exclusion..) based on http://maven.apache.org/plugins/maven-assembly-plugin/assembly.html#class_dependencySet but nothing worked.

Can some one provide me with specific statements that I should change in my pom or assembly files to address 1 and 2-thanks

Best Answer

The basic thing you should change is to create a separate module where you do the packaging which will look like this.

   +-- root (pom.xml)
        +--- mod-1 (pom.xml)
        +--- mod-2 (pom.xml)
        +--- mod-assembly (pom.xml)

The pom in the mod-assembly will look like this:

<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>

  <parent>
    <groupId>org.test.parent</groupId>
    <artifactId>root</artifactId>
    <version>1.0.0-SNAPSHOT</version>
  </parent>

  <artifactId>dist</artifactId>
  <packaging>pom</packaging>

  <name>Packaging Test : Distribution</name>

  <dependencies>
    <dependency>
      <groupId>${project.groupId}</groupId>
      <artifactId>module-one</artifactId>
      <version>${project.version}</version>
    </dependency>
    <dependency>
      <groupId>${project.groupId}</groupId>
      <artifactId>module-two</artifactId>
      <version>${project.version}</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <executions>
          <execution>
            <id>make-bundles</id>
            <goals>
              <goal>single</goal>
            </goals>
            <phase>package</phase>
            <configuration>
              <descriptors>
                <descriptor>proj1-assembly.xml</descriptor>
              </descriptors>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

</project>

That will solve the problem with running maven-assembly-plugin in every child and the problem with the dummy descriptor. Here you can find a real example of such structure.

Furthermore having the modules in one folder and the dependencies in an other folder you can use a assembly descriptor like this:

  <id>bin</id>
  <formats>
    <format>zip</format>
  </formats>
  <includeBaseDirectory>false</includeBaseDirectory>
  <dependencySets>
    <dependencySet>
          <useProjectArtifact>false</useProjectArtifact>
          <useTransitiveDependencies>true</useTransitiveDependencies>
          <outputDirectory>lib</outputDirectory>
          <unpack>false</unpack>
          <excludes>
            <exclude>${project.groupId}:*:*</exclude>
          </excludes>
      </dependencySet>
  </dependencySets>
  <moduleSets>
    <moduleSet>
      <useAllReactorProjects>true</useAllReactorProjects>
      <binaries>
        <outputDirectory>modules</outputDirectory>
        <unpack>false</unpack>
      </binaries>
    </moduleSet>
  </moduleSets>