skip to content

How do active profiles affect the effective POM, and how do you tell which profiles are active?

level: seniorimportance: must knowfreq 50%

answer

  1. conditional config slice
  2. merged last, on top
  3. -P / settings / activeByDefault / activation
  4. -P disables activeByDefault
  5. help:active-profiles to inspect

basics

~20 s

Active profiles inject extra dependencies, plugins, properties, or repositories into the computed model, merged on top after inheritance. Profiles can be activated by -P, settings.xml, activeByDefault, OS, JDK, property, or file. Check with mvn help:active-profiles or help:effective-pom.

solid answer

~40 s

A `<profile>` is a conditional slice of POM configuration. When active, its `<dependencies>`, `<plugins>`, `<properties>`, `<repositories>`, etc. are merged into the effective model on top of the inherited/base values — so they are the last word before interpolation. Activation routes: explicit `-Pname` on the CLI, `<activeProfiles>` in settings.xml, `<activeByDefault>true</activeByDefault>`, or `<activation>` conditions (`<jdk>`, `<os>`, `<property>`, `<file>`). A subtlety: declaring `-P` for any profile disables `activeByDefault` profiles unless they're also explicitly chosen. Profiles can live in the POM, in `settings.xml`, or `~/.m2/settings.xml`. To see what's active, run `mvn help:active-profiles` (lists which are on and their source) or `mvn help:effective-pom -P prod` (shows the merged result). Profiles enable environment-specific builds (dev/ci/prod) without forking the POM.

code

bash · 4 lines
bash
mvn help:active-profiles
mvn package -Pprod
mvn package -Denv=prod
mvn help:effective-pom -Pprod -Doutput=eff-prod.xml

go deeper

for a junior

Knows -P activates a profile and that profiles add extra config.

for a middle

Lists the activation mechanisms and that profiles merge on top of the base model.

for a senior

Handles the activeByDefault gotcha, settings vs POM profile limits, and inspects with help:active-profiles.

for a principal

Standardizes environment profile strategy across repos and avoids brittle activation, favoring explicit properties/CI flags.

## What a profile is A `<profile>` is a named, conditional set of build configuration inside a POM (or `settings.xml`). When the profile is **active**, its contents are merged into the effective POM; when inactive, they contribute nothing. This lets one POM serve multiple environments. ## Where profiles can be defined - In the project `pom.xml` under `<profiles>`. - In `settings.xml` (per-user `~/.m2/settings.xml` or global) under `<profiles>` — but settings profiles can only carry a subset (repositories, properties, plugin repositories), not arbitrary build/plugin config. ## Activation routes 1. **CLI**: `mvn -Pprod,fast` activates named profiles. A leading `!` deactivates: `-P!slow`. 2. **settings.xml `<activeProfiles>`**: always-on for that machine. 3. **`<activeByDefault>true</activeByDefault>`**: on unless another profile is explicitly activated via `-P` (a common gotcha — naming any profile on the CLI can silently switch off your default). 4. **`<activation>` conditions**: `<jdk>17</jdk>`, `<os><family>windows</family></os>`, `<property><name>env</name><value>ci</value></property>`, or `<file><exists>...</exists></file>`. ## How injection merges Profiles are applied AFTER inheritance is resolved, layered on top of the base model. So a property set in an active profile overrides the same property from the parent or project. Then property interpolation runs. ```xml <profiles> <profile> <id>prod</id> <activation> <property><name>env</name><value>prod</value></property> </activation> <properties> <build.target>production</build.target> </properties> <dependencies> <dependency> <groupId>com.example</groupId> <artifactId>prod-only</artifactId> <version>1.0.0</version> </dependency> </dependencies> </profile> </profiles> ``` Activate with `mvn package -Denv=prod` or `mvn package -Pprod`. ## Inspecting active profiles ```bash mvn help:active-profiles # which profiles are active and from where mvn help:effective-pom -Pprod # the merged model with prod applied ``` `help:active-profiles` reports the source (pom, settings, or default) — invaluable when a build behaves differently on CI vs locally. ## Common pitfalls - Relying on `activeByDefault` and then passing any `-P` flag, which disables it. - Putting build/plugin config in a `settings.xml` profile (not supported there). - Assuming profile order; conflicting active profiles merge with later/more-specific values winning, which is hard to reason about — keep them disjoint.

  • Why might a profile that worked locally not activate on CI?
    Activation conditions differ (JDK, OS, a -D property, file existence) or CI passes a -P that disables an activeByDefault profile. Use mvn help:active-profiles on CI to confirm.
  • What's the gotcha with activeByDefault?
    Any profile activated explicitly via -P turns off all activeByDefault profiles unless they too are named on the command line.
  • Can a settings.xml profile add a plugin to the build?
    No. settings.xml profiles are limited to repositories, plugin repositories, and properties; they cannot carry build/plugin configuration.

saying these in an interview costs you the question

  • Saying inactive profile config still affects the build.
  • Believing -P adds to activeByDefault rather than potentially disabling it.
  • Claiming settings.xml profiles can declare arbitrary plugins/dependencies for the build.

context