What is the Maven reactor, and how do you build only a single module out of a large multi-module project from the command line?
answer
- reactor = order + selection
- -pl / --projects selector list
- path OR :artifactId
- subset != upstream included
- needs -am for deps
basics
~10 sThe reactor is Maven's engine that figures out which modules to build and in what order based on dependencies. To build one module, run from the root: mvn install -pl :artifactId (or -pl module-path).
solid answer
~40 sIn a multi-module project the root (aggregator) pom lists `<modules>`. When you run Maven there, the **reactor** collects all listed modules, sorts them topologically by their inter-module dependencies, and builds them in that order. To restrict the build to specific modules you pass `-pl`/`--projects` with a comma-separated list of project selectors. A selector is either a relative directory path (e.g. `-pl core,web`) or a `groupId:artifactId` / `:artifactId` coordinate. Running `mvn install -pl :payments` builds just that one module. The catch: if `payments` depends on `core` and `core` isn't already in your local repository, the build fails because the reactor only includes what you selected. That's why `-pl` is usually combined with `-am` (also-make) to pull in upstream dependencies.
code
bash · 4 lines# from the aggregator root
mvn install -pl :payments # one module by artifactId
mvn install -pl core,web # two modules by path
mvn install -pl !legacy # all modules except legacygo deeper
Know that -pl/--projects limits the build to named modules and selectors can be a path or :artifactId.
Understand the reactor computes build order from inter-module dependencies and that -pl excludes upstream modules unless -am is added.
Combine selectors with -am/-amd/-rf to design fast incremental builds and reason about resolution from local repo vs reactor.
Define CI strategy: which modules to build per change, when to rely on installed artifacts vs reactor inclusion, and the failure modes of partial builds across teams.
## What is a multi-module project A Maven **multi-module** (a.k.a. aggregator) project has a parent/root `pom.xml` with `<packaging>pom</packaging>` and a `<modules>` section listing child directories. Each child is itself a Maven project. Building the root builds all the children together. ## What is the reactor The **reactor** is the part of Maven that, given a set of modules, (1) reads each module's dependencies, (2) computes a dependency graph, and (3) sorts the modules into a valid build order (topological sort) so that a module is always built after the modules it depends on. It then runs the requested lifecycle (e.g. `install`) on each in turn. Inter-module dependencies are recognized when one module declares another as a `<dependency>` using the same `groupId:artifactId:version`. ## Building a subset with -pl / --projects `-pl` (long form `--projects`) takes a comma-separated list of **project selectors**: - a relative path to the module directory: `-pl core,services/payments` - a coordinate `groupId:artifactId`: `-pl com.acme:payments` - a short coordinate `:artifactId`: `-pl :payments` - (Maven 3.2.1+) prefix `!` or `-` to *exclude* a module: `-pl !legacy` Maven then runs the goals only on the selected modules (still in correct reactor order among themselves). ## The dependency gotcha `-pl` does **not** automatically include upstream modules. If `payments` depends on sibling `core`, and `core` is not present in your local repo (`~/.m2/repository`), the build of `payments` cannot resolve it and fails. Solutions: install `core` first, or add `-am` (also-make) so the reactor includes `core` automatically. ```bash # build only payments (may fail if core isn't installed) mvn install -pl :payments # build payments AND everything it depends on mvn install -pl :payments -am ``` ## Why it matters On big repos, full builds are slow. Reactor selectors let you build just what you touched, dramatically shortening the feedback loop in local dev and CI.
- Why might `mvn install -pl :payments` fail even though the module compiles fine in a full build?Because -pl excludes its sibling dependencies; if an upstream module like core isn't already in the local repo, dependency resolution fails. Add -am to include upstream modules.
- What forms can a -pl selector take?A relative directory path, a full groupId:artifactId, a short :artifactId, and (Maven 3.2.1+) a leading ! or - to exclude a module.
The reactor is like a chef reading a recipe tree: it figures out you must chop onions before the sauce, sauce before the dish — and -pl says 'only make these dishes', not their prep.
saying these in an interview costs you the question
- Thinking -pl automatically builds dependency modules too
- Believing the reactor ignores build order when a subset is selected
- Confusing -pl (projects) with -P (profiles)