The last post of this series introduced you to a couple of useful options to manage dependencies in maven. In this post, we’ll focus on multi-module builds — a.k.a., reactor builds. Starting with version 2.1, Maven provides a couple of very interesting options allowing to avoid re-building all modules after a small change. This can save a lot of waiting for the build to complete and is what this post is all about.
To illustrate the topic, let’s imagine a simple multi-module project:
- Project is the ‘root’ project, in which the others modules are declared
- Module-A is a simple project
- Module-B depends on Module-A
- Module-C depends on Module-A
- Module-D depends on Module-C
To build all those projects at once, you normally go to the root (i.e., the pom of “Project”), and then do a: mvn clean install
[INFO] Reactor Summary:
[INFO] Module A ……………………………… SUCCESS [2.392s]
[INFO] Module B ……………………………… SUCCESS [0.076s]
[INFO] Module C ……………………………… SUCCESS [0.038s]
[INFO] Module D ……………………………… SUCCESS [0.044s]
[INFO] Reactor ……………………………….. SUCCESS [0.963s]
This will compile the sources, execute the tests, do the packaging and the installation of all modules.
Building only the reactor pom
Sometimes, however, what you want is to just ‘build’ the reactor pom and not the sub-modules. This is possible using the --non-recursive (or -N) parameter. With it, maven does not recurs in sub-projects, and builds the reactor pom only.
Resuming a build
Alternatively, the following option allows resuming a ‘reactor’ build starting from a specified project namely, the --resume-from (-rf) option. With it, Maven builds the listed module and all the following modules only.
mvn clean install –rf module-B => Builds module-B, C & D
I generally use this option when my build fails because of a pretty simple error (that does not impact any already built projects). Instead of restarting the build from scratch and wait, I can restart the build from the failing project. This allows for faster feedback on the fix while the remaining projects will also be compiled.
Selecting the projects to build
Another useful option is the --project options (or -pl). This argument allows to select the project to build. For example,
mvn clean install –pl module-C => Builds only the module-C
mvn clean install –pl module-C,module-D => Builds the module-C & D
There are three details to know on this option:
- the command must be called from the root project (reactor pom)
- to specify a module, you can either use the path or the artifactId
- if you specify several modules, they are comma-separated without SPACES
The --projects parameter can be accompanied with the --also-make (-am) parameter. This second option also builds the projects required by the project specified in the project list.
mvn clean install –pl module-C –am => builds module A & C
mvn clean install –pl module-D –am => builds module-A, C & D
mvn clean install –pl module-A –am => builds only A
This option is useful when you have updated your working copy and you want to be sure to build the dependencies (an so test against the latest version) of the project you are working on. It is also really useful if you are building a ‘distribution’ (War, EAR or Archive) and you want to be sure to include the latest version of the artifacts included in the distribution.
The previous option allows to build the dependencies of a given project. The --also-make-dependents (or just -amd) builds the projects depending on the project listed in the --projects options.
mvn clean install -pl module-C –amd => Build the module-C & D
mvn clean install -pl module-A –amd => Build all modules
This option is really useful to check the impact of your changes on the projects depending on the modified projects.
The maven-reactor-plugin and the make-scm-changes
With those options, you can save a lot of time when building multi-module builds. If you are using an older version of Maven, you can still use the maven-reactor-plugin offering similar features (but with a longer command line to write). This plugin also offers one great goal to detect your changes.
This goal detects your changes (using to the information in the pom) and build the impacted projects and the dependent projects. For example, if you have modified a class from module-C, it will build module-C and D as well.