title: How to structure a multi-modules Maven project to compile it at once?
body: <p>I have a Maven project with multiple modules and sub-modules and i want to compile it at once, i.e. using only one call to "mvn clean install".</p>
  
  <p>For a basic project, the following structure would work:</p>
  
  <pre><code>.
  ├── modules
  │   ├── moduleA
  │   │   └── pom.xml &lt;--- Module A POM
  │   ├── moduleB
  │   │   └── pom.xml &lt;--- Module B POM
  │   └── pom.xml     &lt;--- Super POM (at the root of "modules" folder)
  └── pom.xml         &lt;--- Aggregator POM
  </code></pre>
  
  <p>With the aggregator being:</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;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"&gt;
      &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
  
      &lt;groupId&gt;org.test&lt;/groupId&gt;
      &lt;artifactId&gt;aggregator&lt;/artifactId&gt;
      &lt;packaging&gt;pom&lt;/packaging&gt;
      &lt;version&gt;1.0.0-SNAPSHOT&lt;/version&gt;
  
      &lt;modules&gt;
          &lt;module&gt;modules&lt;/module&gt;
          &lt;module&gt;modules/moduleA&lt;/module&gt;
          &lt;module&gt;modules/moduleB&lt;/module&gt;
      &lt;/modules&gt;
  
  &lt;/project&gt;
  </code></pre>
  
  <p>The Super POM:</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;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"&gt;
      &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
  
      &lt;groupId&gt;org.test&lt;/groupId&gt;
      &lt;artifactId&gt;super-pom&lt;/artifactId&gt;
      &lt;packaging&gt;pom&lt;/packaging&gt;
      &lt;version&gt;1.0.0-SNAPSHOT&lt;/version&gt;
  
      &lt;dependencyManagement&gt;
          &lt;dependencies&gt;
              &lt;dependency&gt;
                  &lt;groupId&gt;junit&lt;/groupId&gt;
                  &lt;artifactId&gt;junit&lt;/artifactId&gt;
                  &lt;version&gt;4.11&lt;/version&gt;
                  &lt;scope&gt;test&lt;/scope&gt;
              &lt;/dependency&gt;
          &lt;/dependencies&gt;
      &lt;/dependencyManagement&gt;
  
  &lt;/project&gt;
  </code></pre>
  
  <p>Module A's POM:</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;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"&gt;
      &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
  
      &lt;artifactId&gt;moduleA&lt;/artifactId&gt;
  
      &lt;parent&gt;
          &lt;groupId&gt;org.test&lt;/groupId&gt;
          &lt;artifactId&gt;super-pom&lt;/artifactId&gt;
          &lt;version&gt;1.0.0-SNAPSHOT&lt;/version&gt;
      &lt;/parent&gt;
  
  &lt;/project&gt;
  </code></pre>
  
  <p>Module B is similar.</p>
  
  <p>When at the root of the project, running "mvn clean install" command gives (after cleaning up the .m2/repository folder):</p>
  
  <pre><code>[...]
  [INFO] ------------------------------------------------------------------------
  [INFO] Reactor Summary:
  [INFO] 
  [INFO] super-pom .......................................... SUCCESS [  0.450 s]
  [INFO] moduleA ............................................ SUCCESS [  1.746 s]
  [INFO] moduleB ............................................ SUCCESS [  0.029 s]
  [INFO] agregator .......................................... SUCCESS [  0.006 s]
  [INFO] ------------------------------------------------------------------------
  [INFO] BUILD SUCCESS
  </code></pre>
  
  <p>Now if I want something that is more complex (but still using one super POM), such as:</p>
  
  <pre><code>.
  ├── modules
  │   ├── lib1
  │   │   ├── moduleA1
  │   │   │   └── pom.xml
  │   │   ├── moduleB1
  │   │   │   └── pom.xml
  │   │   └── pom.xml      &lt;--- lib1 aggregator POM
  │   ├── lib2
  │   │   ├── moduleA2
  │   │   │   └── pom.xml
  │   │   ├── moduleB2
  │   │   │   └── pom.xml
  │   │   └── pom.xml      &lt;--- lib2 aggregator POM
  │   └── pom.xml          &lt;--- Super POM
  └── pom.xml              &lt;--- Aggregator POM
  </code></pre>
  
  <p>With the root POM being:</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;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"&gt;
      &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
  
      &lt;groupId&gt;org.test&lt;/groupId&gt;
      &lt;artifactId&gt;agregator&lt;/artifactId&gt;
      &lt;packaging&gt;pom&lt;/packaging&gt;
      &lt;version&gt;1.0.0-SNAPSHOT&lt;/version&gt;
  
      &lt;modules&gt;
          &lt;module&gt;modules&lt;/module&gt;
          &lt;module&gt;modules/lib1&lt;/module&gt;
          &lt;module&gt;modules/lib2&lt;/module&gt;
      &lt;/modules&gt;
  
  &lt;/project&gt;
  </code></pre>
  
  <p>Lib1 POM:</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;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"&gt;
      &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
  
      &lt;groupId&gt;org.test&lt;/groupId&gt;
      &lt;artifactId&gt;lib1-agregator&lt;/artifactId&gt;
      &lt;packaging&gt;pom&lt;/packaging&gt;
      &lt;version&gt;1.0.0-SNAPSHOT&lt;/version&gt;
  
      &lt;modules&gt;
          &lt;module&gt;moduleA1&lt;/module&gt;
          &lt;module&gt;moduleB1&lt;/module&gt;
      &lt;/modules&gt;
  
  &lt;/project&gt;
  </code></pre>
  
  <p>And, for instance moduleA1 POM:</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;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"&gt;
      &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
  
      &lt;artifactId&gt;moduleA1&lt;/artifactId&gt;
  
      &lt;parent&gt;
          &lt;groupId&gt;org.test&lt;/groupId&gt;
          &lt;artifactId&gt;super-pom&lt;/artifactId&gt;
          &lt;version&gt;1.0.0-SNAPSHOT&lt;/version&gt;
      &lt;/parent&gt;
  
  &lt;/project&gt;
  </code></pre>
  
  <p>Maven does not manage to resolve the POM files (after cleaning up the .m2/repository folder):</p>
  
  <pre><code>[INFO] Scanning for projects...
  [ERROR] [ERROR] Some problems were encountered while processing the POMs:
  [WARNING] 'parent.relativePath' of POM org.test:moduleA1:[unknown-version] (/Users/ben/IdeaProjects/ComplexMavenStructure/modules/lib1/moduleA1/pom.xml) points at org.test:lib1-agregator instead of org.test:super-pom, please verify your project structure @ line 7, column 13
  [FATAL] Non-resolvable parent POM for org.test:moduleA1:[unknown-version]: Could not find artifact org.test:super-pom:pom:1.0.0-SNAPSHOT and 'parent.relativePath' points at wrong local POM @ line 7, column 13
  [WARNING] 'parent.relativePath' of POM org.test:moduleB1:[unknown-version] (/Users/ben/IdeaProjects/ComplexMavenStructure/modules/lib1/moduleB1/pom.xml) points at org.test:lib1-agregator instead of org.test:super-pom, please verify your project structure @ line 7, column 13
  [FATAL] Non-resolvable parent POM for org.test:moduleB1:[unknown-version]: Could not find artifact org.test:super-pom:pom:1.0.0-SNAPSHOT and 'parent.relativePath' points at wrong local POM @ line 7, column 13
  [WARNING] 'parent.relativePath' of POM org.test:moduleA2:[unknown-version] (/Users/ben/IdeaProjects/ComplexMavenStructure/modules/lib2/moduleA2/pom.xml) points at org.test:lib2-agregator instead of org.test:super-pom, please verify your project structure @ line 7, column 13
  [FATAL] Non-resolvable parent POM for org.test:moduleA2:[unknown-version]: Could not find artifact org.test:super-pom:pom:1.0.0-SNAPSHOT and 'parent.relativePath' points at wrong local POM @ line 7, column 13
  [WARNING] 'parent.relativePath' of POM org.test:moduleB2:[unknown-version] (/Users/ben/IdeaProjects/ComplexMavenStructure/modules/lib2/moduleB2/pom.xml) points at org.test:lib2-agregator instead of org.test:super-pom, please verify your project structure @ line 7, column 13
  [FATAL] Non-resolvable parent POM for org.test:moduleB2:[unknown-version]: Could not find artifact org.test:super-pom:pom:1.0.0-SNAPSHOT and 'parent.relativePath' points at wrong local POM @ line 7, column 13
   @ 
  [ERROR] The build could not read 4 projects -&gt; [Help 1]
  [ERROR]   
  [ERROR]   The project org.test:moduleA1:[unknown-version] (/Users/ben/IdeaProjects/ComplexMavenStructure/modules/lib1/moduleA1/pom.xml) has 1 error
  [ERROR]     Non-resolvable parent POM for org.test:moduleA1:[unknown-version]: Could not find artifact org.test:super-pom:pom:1.0.0-SNAPSHOT and 'parent.relativePath' points at wrong local POM @ line 7, column 13 -&gt; [Help 2]
  [ERROR]   
  [ERROR]   The project org.test:moduleB1:[unknown-version] (/Users/ben/IdeaProjects/ComplexMavenStructure/modules/lib1/moduleB1/pom.xml) has 1 error
  [ERROR]     Non-resolvable parent POM for org.test:moduleB1:[unknown-version]: Could not find artifact org.test:super-pom:pom:1.0.0-SNAPSHOT and 'parent.relativePath' points at wrong local POM @ line 7, column 13 -&gt; [Help 2]
  [ERROR]   
  [ERROR]   The project org.test:moduleA2:[unknown-version] (/Users/ben/IdeaProjects/ComplexMavenStructure/modules/lib2/moduleA2/pom.xml) has 1 error
  [ERROR]     Non-resolvable parent POM for org.test:moduleA2:[unknown-version]: Could not find artifact org.test:super-pom:pom:1.0.0-SNAPSHOT and 'parent.relativePath' points at wrong local POM @ line 7, column 13 -&gt; [Help 2]
  [ERROR]   
  [ERROR]   The project org.test:moduleB2:[unknown-version] (/Users/ben/IdeaProjects/ComplexMavenStructure/modules/lib2/moduleB2/pom.xml) has 1 error
  [ERROR]     Non-resolvable parent POM for org.test:moduleB2:[unknown-version]: Could not find artifact org.test:super-pom:pom:1.0.0-SNAPSHOT and 'parent.relativePath' points at wrong local POM @ line 7, column 13 -&gt; [Help 2]
  [ERROR] 
  [ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
  [ERROR] Re-run Maven using the -X switch to enable full debug logging.
  [ERROR] 
  [ERROR] For more information about the errors and possible solutions, please read the following articles:
  [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/ProjectBuildingException
  [ERROR] [Help 2] http://cwiki.apache.org/confluence/display/MAVEN/UnresolvableModelException
  </code></pre>
  
  <p>I need to first build the super pom:</p>
  
  <pre><code>cd modules/
  mvn clean install
  </code></pre>
  
  <p>And only then will it compile:</p>
  
  <pre><code>[INFO] Reactor Summary:
  [INFO] 
  [INFO] super-pom .......................................... SUCCESS [  0.271 s]
  [INFO] moduleA1 ........................................... SUCCESS [  1.202 s]
  [INFO] moduleB1 ........................................... SUCCESS [  0.027 s]
  [INFO] lib1-agregator ..................................... SUCCESS [  0.006 s]
  [INFO] moduleA2 ........................................... SUCCESS [  0.027 s]
  [INFO] moduleB2 ........................................... SUCCESS [  0.022 s]
  [INFO] lib2-agregator ..................................... SUCCESS [  0.007 s]
  [INFO] agregator .......................................... SUCCESS [  0.007 s]
  [INFO] ------------------------------------------------------------------------
  [INFO] BUILD SUCCESS
  </code></pre>
  
  <p>How would you structure the project to make it work without this two-steps compilation?</p>
  
  <p>[EDIT]: as discussed in the comments, adding the relativePath of the Super POM to the modules POMs would make the code compile with one command line.</p>
  
  <p>However, if I want to distribute only lib1 to some developers, even though my super POM is on a Maven repository, lib1 would not compile without the whole project structure. This makes the project less modular.</p>