How does Maven merge inherited and management sections into the effective model? Give the precedence rules for inheritance vs. override.
answer
- chain: SuperPOM->parent->child
- scalars = nearest wins
- lists = combine by coordinates
- management = default versions only
- combine.children / combine.self
basics
~20 sMaven merges from the Super POM up through parents to the child, with child values overriding parent values. Lists (dependencies, plugins) accumulate; scalar values are replaced. Management sections supply defaults the child can use without re-specifying versions.
solid answer
~40 sModel building walks the inheritance chain from the Super POM down to the leaf project. For scalar elements (e.g., `<version>`, `<packaging>`), the most specific (child) value wins. For collections like `<dependencies>` and `<build><plugins>`, entries are combined; a child entry with the same coordinates overrides the matching inherited one rather than duplicating it. `<dependencyManagement>` and `<pluginManagement>` do NOT add anything to the build by themselves — they define default versions/config that take effect only when a matching dependency/plugin is actually declared (in this POM or an inherited one). Properties are inherited and overridable. Profiles are merged last on top of the computed model. The combine semantics can be tuned with `combine.children` / `combine.self` attributes on configuration elements. The effective POM (`mvn help:effective-pom`) shows the final merged result.
code
xml · 13 lines<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration combine.children="append">
<includes>
<include>**/*Spec.java</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>go deeper
Knows child overrides parent and that there's a help:effective-pom to check.
Distinguishes scalar override vs list combine and what management sections do.
Predicts merge outcomes, uses combine.self/combine.children, and debugs via the effective POM.
Designs org-wide parent/BOM strategies leveraging management sections and merge semantics to control sprawl.
## The merge pipeline The **Maven Model Builder** assembles the effective POM by processing the inheritance chain: Super POM -> ... -> parent -> child, then applying active profiles, then interpolating properties. ## Scalars vs collections - **Scalar elements** (single values): `<version>`, `<packaging>`, `<finalName>`, `<sourceDirectory>`, etc. The nearest/most specific definition wins — a child overrides its parent. - **Collections**: `<dependencies>`, `<build><plugins>`, `<repositories>`, `<modules>`. Inherited and local entries are **combined**. When a child declares an item with the same identity (groupId:artifactId) as an inherited one, the child's version replaces it — you do not get two copies. ## Management sections (defaults, not activations) - `<dependencyManagement>`: declares versions/scope/exclusions that apply ONLY when some `<dependencies>` entry (here or inherited) names the same groupId:artifactId without its own version. It centralizes versions; it never puts a jar on the classpath by itself. - `<pluginManagement>`: same idea for plugins — sets default version/configuration used when a plugin is actually bound in `<build><plugins>`. ```xml <dependencyManagement> <dependencies> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.14.0</version> </dependency> </dependencies> </dependencyManagement> <!-- elsewhere / in a child --> <dependencies> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <!-- no version: inherited from management --> </dependency> </dependencies> ``` ## Configuration merge control Plugin `<configuration>` blocks merge child-into-parent. You can override the default behavior with attributes: - `combine.children="append"` — append child list items to the parent's instead of replacing. - `combine.self="override"` — replace the parent element entirely. ## Properties and interpolation `<properties>` are inherited and overridable; after merging, Maven interpolates `${...}` references (project fields, properties, settings, env). Profiles are merged last, so an active profile can override anything computed so far. ## Verifying Always confirm with `mvn help:effective-pom`. Surprises (a version you didn't set, a plugin config that didn't append) are almost always explained by these merge rules.
- Does <dependencyManagement> add a dependency to the build?No. It only sets default version/scope/exclusions used when a matching <dependencies> entry omits them. Nothing reaches the classpath until the dependency is actually declared.
- If a child and parent both declare the same plugin configuration list, what happens by default?By default the child's list replaces the parent's. Add combine.children="append" to merge them instead.
saying these in an interview costs you the question
- Saying dependencyManagement puts jars on the classpath.
- Claiming inherited and child dependency lists are blindly concatenated even for the same coordinates (duplicates).
- Forgetting profiles merge LAST and can override everything.