How to structure a multi-modules Maven project to compile it at once?
Let me start like you did, but I name the things a little bit differently:
.
├── modules-root
│ ├── moduleA
│ │ └── pom.xml <--- Module A POM
│ ├── moduleB
│ │ └── pom.xml <--- Module B POM
│ └── pom.xml <--- modules root
└── pom.xml <--- project-root
Let's start with the project-root
, which 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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.test</groupId>
<artifactId>project-root</artifactId>
<packaging>pom</packaging>
<version>1.0.0-SNAPSHOT</version>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
<modules>
<module>modules-root</module>
</modules>
</project>
The module-parent
will look like this. I will emphasis that this contains only the reference to the moduleA
and moduleB
and will inherit from the project-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>
<parent>
<groupId>org.test</groupId>
<artifactId>project-root</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<groupId>org.test.module</groupId>
<artifactId>module-parent</artifactId>
<packaging>pom</packaging>
<modules>
<module>moduleA</module>
<module>moduleB</module>
</modules>
</project>
moduleA
will look like this. Pay attention that this will inherit from module-parent
(parent) which is exactly one level above...
<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>
<parent>
<groupId>org.test.module</groupId>
<artifactId>module-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>moduleA</artifactId>
<packaging>..</packaging>
<....other dependencies..>
</project>
If you use this kind of structure you can simply go to the project-root
level and do:
mvn clean install
Furthermore afterwards you can use things like this:
mvn -pl moduleA ...
...to build only moduleA (but stay at the project-root
level...).
module-parent
might look like wasted or superfluous in this example, but if you get more modules you could define their supplemental dependencies via dependencyManagement
or may changing plugin configurations via pluginManagement
which will only be used in this sub area (moduleA, moduleB, ...). If your project becomes larger, you will get more module-parents
in parallel..which contain different parts of your applications...and different intentions which can be achieved with this structure.
One more thing is to mention; I have changed the groupId
from org.test
to org.test.module
in the module-parent
. This is sometimes useful if you have a large number of modules cause the groupId
represents the folder structure in your repository (as java packages do in a Java project)... this give you an better overview...
The project-root
is the location to define the overall usable dependencies via dependencyManagement
etc....and the used plugins which should be defined via pluginManagement
... or may be using maven-enforcer-plugin to define overall project rules...
Typical scenarios for this kind of structure are Java EE projects or other large projects (may be with 300...or 1000 modules yes they exist)...
If you get more modules you can use the multi-thread capability of maven and build your project with:
mvn -T 4 clean install
from the project-root
which reduces the build time dramatically.