skip to content

Reactor CLI Options

The -pl, -am, -amd, and -rf selectors that build only part of the reactor or resume after a failed module. Interviewers ask because these flags are how a large monorepo build stays tolerable day to day.

on this pageshow

explore

questions

5

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?

level: juniorimportance: must knowfreq 70%

answer

  1. reactor = order + selection
  2. -pl / --projects selector list
  3. path OR :artifactId
  4. subset != upstream included
  5. needs -am for deps

basics

~10 s

The 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 s

In 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
bash
# 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 legacy

go deeper

for a junior

Know that -pl/--projects limits the build to named modules and selectors can be a path or :artifactId.

for a middle

Understand the reactor computes build order from inter-module dependencies and that -pl excludes upstream modules unless -am is added.

for a senior

Combine selectors with -am/-amd/-rf to design fast incremental builds and reason about resolution from local repo vs reactor.

for a principal

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)

context

open as a page

Explain the difference between -am (--also-make) and -amd (--also-make-dependents), and when you'd reach for each.

level: middleimportance: must knowfreq 60%

basics

~20 s

-am adds the modules your selected modules depend ON (upstream), so the build can resolve them. -amd adds the modules that depend on your selected modules (downstream), so you can verify nothing breaks. Both are used with -pl.

open as a page

A 40-module reactor build failed at module 27. How do you restart without rebuilding the first 26, and what are the caveats of doing so?

level: middleimportance: should knowfreq 50%

basics

~10 s

Re-run with -rf :failedModule (--resume-from). Maven starts the reactor at that module and continues to the end, skipping the modules that already succeeded.

open as a page

Design a CI strategy that builds only the modules affected by a pull request in a large reactor. Which selectors and flags would you use, and what are the correctness risks?

level: seniorimportance: should knowfreq 35%

basics

~20 s

Detect changed module dirs from the git diff, then run mvn verify -pl <changed> -amd (and -am if upstreams may need rebuilding). This builds the touched modules plus everything that depends on them, skipping unaffected modules.

open as a page

Walk through the selector syntax accepted by -pl, including path vs coordinate forms and exclusions, and a pitfall teams hit with module names.

level: seniorimportance: nice to knowfreq 25%

basics

~20 s

-pl accepts comma-separated selectors: a relative module path (core/api), a full groupId:artifactId, or short :artifactId. Prefix with ! or - to exclude. A common pitfall: the path is the directory name, which may differ from the artifactId.

open as a page