In this tutorial, we’ll take a quick look at the fundamental concepts of the Maven Reactor and its place in the Maven ecosystem.
We’ll start with the introduction to the Maven Reactor. Next, we’ll set up a simple example of a multi-module Maven project with inter-module dependencies and see the Reactor in action to sort out the build dependencies. We’ll touch upon some available flags that can fine-tune Maven Reactor’s behavior. We’ll conclude by summarizing some of the benefits of using Reactor.
2. Basics of Maven Reactor
Maven Reactor is a built-in part of Maven and manages project dependencies and builds. It is responsible for the execution of Maven builds and ensures that projects are built in the correct order to satisfy the dependencies. The real benefit of the Maven Reactor can be appreciated in complex multi-module projects with many inter-module dependencies.
The Reactor uses a directed acyclic graph (DAG) to determine the build order of the project.
It performs the following functions as part of the Maven core:
- Gathers all the modules available for building
- Organizes the projects into the appropriate build sequence
- Sequentially executes the selected projects
4. Example Use Case
Let’s consider a project that involves developing a web-based application for managing patient information. The project consists of three modules:
- The patient-web module – this module serves as the user interface for the application
- The patient-data module – this module handles all database CRUD operations
- The patient-domain module – this module contains the domain entities that are utilized by the application
In this project, the patient-web module relies on the other two modules since it retrieves and displays data from the persistent storage. On the other hand, the patient-data module depends on the patient-domain module as it needs to access the domain entities to carry out CRUD operations. It’s important to note that the patient-data module is independent of the other two modules.
4.1. Maven Setup
To implement our simple example, let’s set up a multi-module project called sample-reactor-project, comprising three modules. Each of these modules will serve the purposes previously mentioned:
At this point, let’s peek into Project POM:
Essentially, here we have defined a multi-module project with all three modules declared within <module> ..</module> tags in the project pom.
Now, let’s look at the POM for the patient-data module:
Here, we can see that the patient data depends on the patient-domain.
For our use case, we’ll assume the patient-domain module is independent of the rest of the modules and can be built independently. Its POM looks like this:
Finally, the patient-web should have dependencies from both patient-data and patient-domain:
4.2. Maven Reactor in Action
To see the Reactor in action, let’s go to the project’s parent directory (maven-reactor) and execute the mvn clean install.
At this point, Maven will use the Reactor to perform the following tasks:
- Collect all available modules in the project (in this case, patient-web, patient-data, and patient-domain)
- Determine the correct order to build the modules based on their dependencies (in this case, the patient-domain must be built before patient-data, which must be built before the patient-web)
- Build each module in the correct order, ensuring that dependencies are correctly resolved
Here’s the Reactor build order with the successful build:
5. Configuring Reactor
Although Reactor is a part of Maven by default, we can still modify its behavior by utilizing several command line switches. These switches are considered essential as they allow us to govern how the Reactor builds our project. Some of the essential switches to consider are:
- –resume-from: allows us to resume a reactor from a specific project in case it fails in the middle of the build
- –also-make: builds the specified projects and any of their dependencies in the reactor
- –also-make-dependents: builds the specified projects and any projects that depend on them
- –fail-fast: stops the overall build immediately whenever a module build fails (default)
- –fail-at-end: this option continues the reactor build even if a particular module build fails and reports all failed modules at the end instead
- –non-recursive: using this option, we can disable Reactor build and build only the project in the current directory, even if the project’s pom declares other modules
By using these options, we can fine-tune the behavior of the reactor and build our project exactly how we need it.
In this article, we had a quick look at the benefits of using Maven Reactor as part of the Apache Maven ecosystem to build multi-module complex projects taking away the responsibility of resolving the dependencies and order of build from the developer as well as reducing the time to build
As usual, all the code samples shown in this tutorial are available over on GitHub.