skip to content

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%

answer

  1. path | groupId:artifactId | :artifactId
  2. comma-separated, mixable
  3. ! or - to exclude (3.2.1+)
  4. folder != artifactId
  5. quote ! in shell

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.

solid answer

~40 s

`-pl` (`--projects`) takes a comma-separated list where each item is one of: a **relative directory path** to the module (`-pl core,services/api`), a full **coordinate** `groupId:artifactId` (`-pl com.acme:api`), or a **short coordinate** `:artifactId` (`-pl :api`). Since Maven 3.2.1 you can **exclude** modules by prefixing `!` or `-` (`-pl !legacy,!docs` — quote `!` in shells that expand it). The classic pitfall: the **directory name and the artifactId are not necessarily the same**. A folder `payment-service` might contain a module with `<artifactId>payments</artifactId>`. So `-pl payment-service` (path) and `-pl :payments` (coordinate) both work but refer to it differently, and mixing them up causes 'Could not find the selected project in the reactor' errors. Also, selectors are matched against modules actually in the reactor — selecting a module that isn't reachable from the current aggregator fails.

code

bash · 3 lines
bash
mvn install -pl core,:api,services/web   # mixed forms
mvn install -pl com.acme:payments        # full coordinate
mvn install -pl '!legacy,!docs'          # exclusions (quote the !)

go deeper

for a junior

Know the three forms exist: path, full coordinate, short :artifactId.

for a middle

Use exclusions and mixed selector lists correctly.

for a senior

Anticipate the directory-vs-artifactId mismatch and choose a consistent team convention.

for a principal

Codify selector conventions and tooling so CI scripts don't break when modules are renamed or relocated.

## The three selector forms `-pl` / `--projects` parses a comma-separated list. Each token may be: 1. **Relative path** — the module's directory relative to the execution root: `-pl core`, `-pl services/api`. Path separators are `/`. 2. **Full coordinate** — `groupId:artifactId`: `-pl com.acme:api`. 3. **Short coordinate** — `:artifactId` (leading colon, group omitted): `-pl :api`. You can mix forms in one list: `-pl core,:api,services/web`. ## Exclusions (Maven 3.2.1+) Prefix a selector with `!` or `-` to remove it from the build: ```bash mvn install -pl '!legacy,!docs' # build everything except legacy and docs ``` Quote the value in bash/zsh because `!` triggers history expansion. ## The directory-vs-artifactId pitfall There is **no rule** that a module's folder name equals its `<artifactId>`: ```xml <!-- in folder services/payment-service/pom.xml --> <artifactId>payments</artifactId> ``` - Path form: `-pl services/payment-service` - Coordinate form: `-pl :payments` Using `-pl :payment-service` (wrong — that's the folder, not the artifactId) yields `Could not find the selected project in the reactor`. Pick one consistent convention; coordinate form is more robust to directory restructuring, path form is more obvious to newcomers. ## Other gotchas - **Execution root matters**: paths are relative to where you run `mvn`. Running from a subdirectory changes the meaning of relative paths. - **Module must be in the reactor**: `-pl` can only select modules reachable through the aggregator's `<modules>` graph from the current pom; you can't select an unrelated project. - **Combining with -am/-amd/-rf**: selectors used by all of these share the same syntax. ## Quick reference ```bash mvn install -pl core,:api # path + short coordinate mvn install -pl com.acme:web # full coordinate mvn install -pl '!legacy' # exclude ```

  • Why might `-pl :payment-service` fail when the folder is named payment-service?
    Because the colon form matches the <artifactId>, not the directory. If the artifactId is 'payments', use -pl :payments or path form -pl payment-service.
  • How do you exclude modules with -pl and what shell caveat applies?
    Prefix selectors with ! or - (Maven 3.2.1+), e.g. -pl '!legacy'. Quote it in bash/zsh so ! isn't treated as history expansion.

saying these in an interview costs you the question

  • Assuming the module directory name always equals its artifactId
  • Using :folderName instead of :artifactId for the coordinate form
  • Forgetting exclusion needs Maven 3.2.1+ and shell quoting of !

context