skip to content

What activation triggers can automatically enable a Maven profile, and how do they behave?

level: middleimportance: must knowfreq 70%

answer

  1. activeByDefault / property / jdk / os / file
  2. explicit -P kills activeByDefault
  3. property name vs name+value vs !name
  4. jdk range [11,)
  5. file exists / missing
  6. help:active-profiles

basics

~10 s

Besides activating with -P, a profile's <activation> can turn it on automatically: activeByDefault, a property being set, a JDK version range, the OS, or whether a file exists or is missing.

solid answer

~30 s

A profile's `<activation>` block lets Maven enable it without `-P`. The triggers are: `<activeByDefault>true` (on unless another profile is explicitly activated); `<property>` (a system/user property exists, or matches/doesn't match a value via `!`); `<jdk>` (exact like `17` or a range like `[11,)`); `<os>` (name/family/arch/version, e.g. family `windows`); and `<file>` with `<exists>` or `<missing>` (presence/absence of a path, which can use `${project.basedir}`). Multiple conditions in one `<activation>` are ANDed in current Maven. A key gotcha: any explicit `-P` activation suppresses all `activeByDefault` profiles, so don't rely on default-active profiles as a fallback once you start naming profiles on the command line.

code

xml · 7 lines
xml
<profile>
  <id>jdk17plus</id>
  <activation>
    <jdk>[17,)</jdk>
    <property><name>env</name><value>ci</value></property>
  </activation>
</profile>

go deeper

for a junior

Know that profiles can auto-activate and that -P forces one on.

for a middle

Know the five triggers and the property name/value/! variants and jdk ranges.

for a senior

Anticipate the activeByDefault-vs-explicit gotcha and use help:active-profiles to debug activation.

for a principal

Design activation strategy so builds stay reproducible across machines, OSes, and CI without surprising auto-activation.

## The `<activation>` block Instead of always typing `-P`, you can declare conditions under `<activation>` so Maven decides when a profile is on. The supported triggers: ### 1. activeByDefault ```xml <activation><activeByDefault>true</activeByDefault></activation> ``` The profile is on **unless** any profile is explicitly activated (e.g. via `-P` or another profile's activation), at which point ALL `activeByDefault` profiles switch off. This is the most common footgun. ### 2. property ```xml <activation> <property><name>env</name><value>prod</value></property> </activation> ``` - `<name>foo</name>` alone → active when property `foo` is set (any value). - name + `<value>` → active only when it equals that value. - `<name>!foo</name>` → active when `foo` is NOT set. - name + `<value>!x` → active when it is set but not equal to `x`. Properties come from `-Dfoo=bar`, settings, or the environment via `env.VARNAME`. ### 3. jdk ```xml <activation><jdk>[11,17)</jdk></activation> ``` Matches a prefix (`<jdk>17</jdk>`) or a version **range** in `[ ] ( )` notation. `[11,)` means 11 and up; `(,11)` means below 11. ### 4. os ```xml <activation> <os><family>windows</family><arch>amd64</arch></os> </activation> ``` Matches by `name`, `family` (windows/unix/mac), `arch`, or `version`. Prefix a value with `!` to negate. ### 5. file exists / missing ```xml <activation> <file><exists>${project.basedir}/.use-local</exists></file> </activation> ``` Active when a file exists (`<exists>`) or is absent (`<missing>`). Useful to auto-detect generated artifacts. ## Combining triggers When several conditions appear in one `<activation>`, current Maven requires **all** of them (logical AND). To OR conditions, use separate profiles. ## Inspecting what's active ```bash mvn help:active-profiles ``` This prints which profiles are active and why — invaluable when activation behaves unexpectedly.

  • What happens to an activeByDefault profile when you run mvn -P someOtherProfile?
    It is deactivated. Explicitly activating any profile on the command line turns off all activeByDefault profiles, so the default no longer applies.
  • How do you activate a profile only when a property is NOT set?
    Use `<property><name>!skipFoo</name></property>` — the leading `!` negates, so the profile activates when `skipFoo` is absent.
  • How can you check which profiles are actually active for a build?
    Run `mvn help:active-profiles`, which lists active profiles and their source.

saying these in an interview costs you the question

  • Assuming activeByDefault always stays on even when you pass -P (it gets disabled).
  • Thinking multiple conditions in one <activation> are ORed — current Maven ANDs them.
  • Believing <jdk> only matches exact versions — it supports ranges.

context