How does Maven resolve a child module's <parent>, and what is the role of <relativePath>?
answer
- default relativePath = ../pom.xml
- filesystem first, then local repo, then remote
- <relativePath/> = skip disk, use repos
- coordinate mismatch = falls through
- deeper layout needs ../../pom.xml
basics
~10 sMaven first looks for the parent POM on disk via <relativePath> (default ../pom.xml), and if not found there falls back to local and remote repositories by coordinates. Setting <relativePath></relativePath> empty forces repository-only lookup.
solid answer
~40 sWhen a child declares `<parent>`, Maven resolves it in two stages. First it checks the filesystem at the `<relativePath>` location — which **defaults to `../pom.xml`** (the directory above the child). If a POM with matching groupId/artifactId/version is there, that file is used directly, so local edits to the parent are picked up without installing it. If `<relativePath>` points nowhere valid, Maven falls back to resolving the parent by coordinates from the local repository (`~/.m2`) and then remote repositories. A common idiom is `<relativePath></relativePath>` (empty) or `<relativePath/>`, which **disables the filesystem lookup** and forces repository resolution — used when the parent is an external published artifact not sitting one directory up. The default `../pom.xml` is why standard nested layouts work with no extra config; deeper or unusual layouts need an explicit relativePath like `../../pom.xml`.
code
xml · 7 lines<!-- external published parent: force repo lookup -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.0</version>
<relativePath/>
</parent>go deeper
Knows children point at a parent and usually it just works without thinking about paths.
Knows the default is ../pom.xml and that empty relativePath uses repositories.
Explains full resolution order and uses relativePath correctly for nested vs external parents.
Sets conventions for parent resolution across repos, avoiding stale-parent and coordinate-mismatch pitfalls at scale.
## What relativePath does A child POM identifies its parent by coordinates (groupId, artifactId, version) inside `<parent>`. But to read the parent's content, Maven must *find the file*. `<relativePath>` is the filesystem hint for where to look. ```xml <parent> <groupId>com.acme</groupId> <artifactId>acme-parent</artifactId> <version>1.0.0</version> <relativePath>../pom.xml</relativePath> <!-- this is also the DEFAULT --> </parent> ``` ## Resolution order 1. **Filesystem via relativePath.** Default is `../pom.xml`. The path may point to a file or a directory (a directory means `<dir>/pom.xml`). If the POM there matches the declared coordinates, it is used — meaning unbuilt local changes in the parent are reflected immediately in the reactor. 2. **Local repository** `~/.m2/repository` by coordinates. 3. **Remote repositories** declared in settings/POM. If none yield a matching POM, the build fails with a non-resolvable parent error. ## The empty relativePath idiom ```xml <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.3.0</version> <relativePath/> <!-- skip filesystem, go straight to repos --> </parent> ``` Use this when the parent is an external/published artifact, not a sibling on disk. It avoids Maven wasting time (or worse, mismatching) on a stray `../pom.xml`. ## Why it matters in monorepos In a typical nested monorepo, children sit one level under the root aggregator, so the default `../pom.xml` Just Works and you can omit relativePath entirely. Flatter or multi-level layouts (e.g. `root/group/module`) need explicit paths such as `../../pom.xml`. Getting this wrong produces 'Non-resolvable parent POM' or, subtly, picking up a wrong/stale parent. ## Gotchas - A coordinate mismatch between `<parent>` and the file at relativePath is treated as 'not found' and falls through to repositories — silent surprises. - Empty `<relativePath/>` and `<relativePath></relativePath>` both disable filesystem lookup.
- Why does spring-boot-starter-parent usage always include <relativePath/>?Because the parent is a published artifact in a remote repo, not a sibling on disk. The empty relativePath skips the futile ../pom.xml filesystem check and resolves it from the repository directly.
- What happens if relativePath points to a POM whose coordinates don't match the <parent> block?Maven treats it as not found at that location and falls back to local/remote repository resolution, which can silently use a different parent than you intended.
saying these in an interview costs you the question
- Saying relativePath is required (it defaults to ../pom.xml).
- Claiming an empty relativePath means 'no parent' rather than 'resolve from repositories'.
- Thinking the parent must always be installed to ~/.m2 before children can build.