title: Managing multi-module dependencies with Maven assembly plugin
body: <p>I use Maven assembly plugin to create an assembly for my multi-module project. There are two separate applications built from this multi-module project, each having a separate set of dependencies. I made a custom assembly descriptor which assembles two directories (for each application) with module builds and their respective dependencies. It does everything fine but one thing - it puts dependencies for both modules to each other's assembly.</p>
  
  <p>The following is a simplified version of my project, that has exactly the same behavior.</p>
  
  <p>Consider a project consisting of two modules and an assembly module:</p>
  
  <pre><code>APP
    module1
    module2
    assembly
  </code></pre>
  
  <p>I have added dependencies purely for demonstration:</p>
  
  <pre><code>com.test.app:module1:jar:1.0
  \- commons-cli:commons-cli:jar:1.2:compile
  
  com.test.app:module2:jar:1.0
  \- commons-daemon:commons-daemon:jar:1.0.8:compile
  </code></pre>
  
  <p>Here's the parent POM:</p>
  
  <pre><code>&lt;project&gt;
    &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
  
    &lt;groupId&gt;com.test&lt;/groupId&gt;
    &lt;artifactId&gt;app&lt;/artifactId&gt;
    &lt;version&gt;1.0&lt;/version&gt;
    &lt;packaging&gt;pom&lt;/packaging&gt;
  
    &lt;modules&gt;
      &lt;module&gt;module1&lt;/module&gt;
      &lt;module&gt;module2&lt;/module&gt;
      &lt;module&gt;assembly&lt;/module&gt;
    &lt;/modules&gt;
  &lt;/project&gt;
  </code></pre>
  
  <p>module1 POM:</p>
  
  <pre><code>&lt;project&gt;
    &lt;parent&gt;
      &lt;groupId&gt;com.test&lt;/groupId&gt;
      &lt;artifactId&gt;app&lt;/artifactId&gt;
      &lt;version&gt;1.0&lt;/version&gt;
    &lt;/parent&gt;
  
    &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
  
    &lt;groupId&gt;com.test.app&lt;/groupId&gt;
    &lt;artifactId&gt;module1&lt;/artifactId&gt;
    &lt;version&gt;1.0&lt;/version&gt;
    &lt;packaging&gt;jar&lt;/packaging&gt;
  
    &lt;dependencies&gt;
      &lt;dependency&gt;
        &lt;groupId&gt;commons-cli&lt;/groupId&gt;
        &lt;artifactId&gt;commons-cli&lt;/artifactId&gt;
        &lt;version&gt;1.2&lt;/version&gt;
      &lt;/dependency&gt;
    &lt;/dependencies&gt;
  &lt;/project&gt;
  </code></pre>
  
  <p>module2 POM:</p>
  
  <pre><code>&lt;project&gt;
    &lt;parent&gt;
      &lt;groupId&gt;com.test&lt;/groupId&gt;
      &lt;artifactId&gt;app&lt;/artifactId&gt;
      &lt;version&gt;1.0&lt;/version&gt;
    &lt;/parent&gt;
  
    &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
  
    &lt;groupId&gt;com.test.app&lt;/groupId&gt;
    &lt;artifactId&gt;module2&lt;/artifactId&gt;
    &lt;version&gt;1.0&lt;/version&gt;
    &lt;packaging&gt;jar&lt;/packaging&gt;
  
    &lt;dependencies&gt;
      &lt;dependency&gt;
        &lt;groupId&gt;commons-daemon&lt;/groupId&gt;
        &lt;artifactId&gt;commons-daemon&lt;/artifactId&gt;
        &lt;version&gt;1.0.8&lt;/version&gt;
      &lt;/dependency&gt;
    &lt;/dependencies&gt;
  &lt;/project&gt;
  </code></pre>
  
  <p>assembly POM:</p>
  
  <pre><code>&lt;project&gt;
    &lt;parent&gt;
      &lt;groupId&gt;com.test&lt;/groupId&gt;
      &lt;artifactId&gt;app&lt;/artifactId&gt;
      &lt;version&gt;1.0&lt;/version&gt;
    &lt;/parent&gt;
  
    &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
  
    &lt;groupId&gt;com.test.app&lt;/groupId&gt;
    &lt;artifactId&gt;assembly&lt;/artifactId&gt;
    &lt;version&gt;1.0&lt;/version&gt;
    &lt;packaging&gt;pom&lt;/packaging&gt;
  
    &lt;build&gt;
      &lt;plugins&gt;
        &lt;plugin&gt;
          &lt;artifactId&gt;maven-assembly-plugin&lt;/artifactId&gt;
          &lt;version&gt;2.2.2&lt;/version&gt;
  
          &lt;executions&gt;
            &lt;execution&gt;
              &lt;id&gt;make-assembly&lt;/id&gt;
              &lt;phase&gt;package&lt;/phase&gt;
  
              &lt;goals&gt;
                &lt;goal&gt;single&lt;/goal&gt;
              &lt;/goals&gt;
            &lt;/execution&gt;
          &lt;/executions&gt;
  
          &lt;configuration&gt;
            &lt;appendAssemblyId&gt;false&lt;/appendAssemblyId&gt;
  
            &lt;descriptors&gt;
              &lt;descriptor&gt;src/main/assembly/descriptor.xml&lt;/descriptor&gt;
            &lt;/descriptors&gt;
          &lt;/configuration&gt;
        &lt;/plugin&gt;
      &lt;/plugins&gt;
    &lt;/build&gt;
  &lt;/project&gt;
  </code></pre>
  
  <p>And finally, the assembly descriptor:</p>
  
  <pre><code>&lt;assembly&gt;
    &lt;id&gt;distribution&lt;/id&gt;
    &lt;includeBaseDirectory&gt;false&lt;/includeBaseDirectory&gt;
  
    &lt;formats&gt;
      &lt;format&gt;dir&lt;/format&gt;
    &lt;/formats&gt;
  
    &lt;moduleSets&gt;
      &lt;moduleSet&gt;
        &lt;useAllReactorProjects&gt;true&lt;/useAllReactorProjects&gt;
  
        &lt;includes&gt;
          &lt;include&gt;com.test.app:module1:jar&lt;/include&gt;
        &lt;/includes&gt;
  
        &lt;binaries&gt;
          &lt;outputDirectory&gt;module1&lt;/outputDirectory&gt;
          &lt;unpack&gt;false&lt;/unpack&gt;
  
          &lt;dependencySets&gt;
            &lt;dependencySet&gt;
              &lt;unpack&gt;false&lt;/unpack&gt;
            &lt;/dependencySet&gt;
          &lt;/dependencySets&gt;
        &lt;/binaries&gt;
      &lt;/moduleSet&gt;
  
      &lt;moduleSet&gt;
        &lt;useAllReactorProjects&gt;true&lt;/useAllReactorProjects&gt;
  
        &lt;includes&gt;
          &lt;include&gt;com.test.app:module2:jar&lt;/include&gt;
        &lt;/includes&gt;
  
        &lt;binaries&gt;
          &lt;outputDirectory&gt;module2&lt;/outputDirectory&gt;
          &lt;unpack&gt;false&lt;/unpack&gt;
  
          &lt;dependencySets&gt;
            &lt;dependencySet&gt;
              &lt;unpack&gt;false&lt;/unpack&gt;
            &lt;/dependencySet&gt;
          &lt;/dependencySets&gt;
        &lt;/binaries&gt;
      &lt;/moduleSet&gt;
    &lt;/moduleSets&gt;
  &lt;/assembly&gt;
  </code></pre>
  
  <p>As you can see, assembly is bind to package phase. So, when I execute</p>
  
  <pre><code>mvn package
  </code></pre>
  
  <p>from parent directory, I have the following assembly</p>
  
  <pre><code>module1/
    commons-cli-1.2.jar
    commons-daemon-1.0.8.jar
    module1-1.0.jar
  module2/
    commons-cli-1.2.jar
    commons-daemon-1.0.8.jar
    module2-1.0.jar
  </code></pre>
  
  <p>Basically, the problem here is that module1 does not depend on commons-daemon, but the assembly plugin has included the dependence. Similarly, with module2 and commons-cli.</p>
  
  <p>Can someone explain why the assembly plugin behaves this way?</p>
  
  <p>An what would be a solution?</p>