How do active profiles affect the effective POM, and how do you tell which profiles are active?
answer
- conditional config slice
- merged last, on top
- -P / settings / activeByDefault / activation
- -P disables activeByDefault
- help:active-profiles to inspect
basics
~20 sActive 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 sA `<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 linesmvn help:active-profiles
mvn package -Pprod
mvn package -Denv=prod
mvn help:effective-pom -Pprod -Doutput=eff-prod.xmlgo deeper
Knows -P activates a profile and that profiles add extra config.
Lists the activation mechanisms and that profiles merge on top of the base model.
Handles the activeByDefault gotcha, settings vs POM profile limits, and inspects with help:active-profiles.
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.