A teammate's build pulls a dependency version nobody declared, and a plugin runs with unexpected config. How do you diagnose this using the effective POM and related tools?
answer
- effective-pom = merged model
- dependency:tree -Dverbose = mediation
- nearest-wins for transitives
- help:active-profiles + effective-settings
- management to force version
basics
~20 sGenerate the effective POM with mvn help:effective-pom to see the fully merged, resolved model and find where the version/config came from. For transitive dependency versions, also use mvn dependency:tree. Check active profiles and settings too.
solid answer
~40 sStart with `mvn help:effective-pom -Doutput=eff.xml` to get the complete merged model — it reveals inherited dependencyManagement versions, plugin configurations from parents/profiles, and resolved properties, so you can trace 'who set this'. For a version that's transitive rather than declared, run `mvn dependency:tree -Dincludes=group:artifact` to see the path and `dependency:tree -Dverbose` for omitted/conflicting nodes and mediation (nearest-wins). If the surprise depends on environment, run `mvn help:active-profiles` and `mvn help:effective-settings` to confirm which profiles/settings are in play (settings.xml mirrors or BOM imports often explain it). Combining the effective POM (declared/managed model) with the dependency tree (resolved graph) pinpoints whether the source is a parent BOM, an active profile, plugin management, or transitive mediation.
code
bash · 4 linesmvn help:effective-pom -Doutput=eff.xml
mvn dependency:tree -Dverbose -Dincludes=com.fasterxml.jackson.core:jackson-databind
mvn help:active-profiles
mvn help:effective-settingsgo deeper
Knows help:effective-pom and dependency:tree exist and roughly what each shows.
Picks the right tool: effective-pom for declared/managed, dependency:tree for transitive mediation.
Systematically isolates source (parent/BOM/profile/settings/transitive) and applies management/exclusions to fix.
Establishes team conventions (BOMs, pinned management, settings hygiene) so these surprises are rare and reproducible.
## The two complementary views Debugging 'where did this come from' needs two lenses: 1. **The effective POM** — the merged *declared* model: what your POM, parents, management sections, and active profiles say. Plugin versions/config and managed dependency versions live here. 2. **The dependency tree** — the *resolved* graph after transitive resolution and mediation. Transitive versions that no POM declares directly show up here. ## Step-by-step diagnosis ### 1. Dump the effective POM ```bash mvn help:effective-pom -Doutput=eff.xml ``` Search it for the plugin or dependency. If the version/config is present here, it came from inheritance (parent/BOM), `<dependencyManagement>`/`<pluginManagement>`, or an active profile. The effective POM flattens all of that into one place. ### 2. Trace transitive dependency versions If the dependency isn't declared anywhere but still appears, it's transitive: ```bash mvn dependency:tree -Dincludes=com.fasterxml.jackson.core:jackson-databind mvn dependency:tree -Dverbose ``` `-Dverbose` shows nodes that were omitted due to **mediation** (Maven's nearest-wins rule: the version closest to the root of the tree is chosen) or conflicts. This tells you which path introduced the version. ### 3. Account for environment ```bash mvn help:active-profiles mvn help:effective-settings ``` Profiles inject config last, and `settings.xml` can add repositories/mirrors or activate profiles per machine. A version difference between two developers' machines is often a profile or settings difference. ### 4. Pin the cause - In effective POM, declared/managed -> a parent or BOM `import` or a profile. - In tree only -> transitive; fix with an explicit declaration or `<dependencyManagement>` entry to force the version (management wins for direct conflicts), or an `<exclusion>`. ## Why management is the fix for transitive surprises Adding the dependency to `<dependencyManagement>` with the desired version forces that version everywhere it appears (directly or transitively for the same coordinates), which is the idiomatic way to override a transitive version cleanly. ## Summary Effective POM answers 'what model did I build', dependency:tree answers 'what graph resolved', and active-profiles/effective-settings answer 'under what environment'. Together they resolve almost any 'unexpected version/config' question.
- The effective POM doesn't mention the dependency at all, yet it's on the classpath. Where is it from?It's transitive. Use mvn dependency:tree (with -Dverbose) to find which direct dependency pulls it and what mediation chose.
- What's the cleanest way to force a transitive dependency to a specific version?Add it to <dependencyManagement> with the desired version; managed versions take precedence for matching coordinates across the graph.
saying these in an interview costs you the question
- Only looking at pom.xml and concluding 'it's not here' for a transitive dependency.
- Confusing the effective POM (declared model) with the resolved dependency tree.
- Ignoring active profiles/settings.xml when a build differs across machines.