What is maven-metadata.xml and what role does it play, especially for SNAPSHOT artifacts?
answer
- index of available versions
- snapshot timestamp+buildNumber
- snapshotVersions mapping
- maven-metadata-<repoid>.xml
- updatePolicy / -U refresh
basics
~20 smaven-metadata.xml is a small index file in a repository that lists the available versions of an artifact (and, for snapshots, the latest timestamped build). Maven reads it to figure out which concrete version to download.
solid answer
~40 s`maven-metadata.xml` is repository metadata that complements the static artifact layout. At the `groupId/artifactId/` level it lists `<versions>`, the `latest`, and the `release` version. Inside a `version` directory for a SNAPSHOT it records the latest `<snapshot>` with its `timestamp` and `buildNumber`, plus a `<snapshotVersions>` mapping so Maven can resolve `1.0-SNAPSHOT` to the concrete uniquely-named file like `artifact-1.0-20240115.103045-7.jar`. Without it, Maven couldn't pick the newest deployed snapshot from a shared remote. Each version has its own `maven-metadata.xml` per repository, and copies exist both remotely and locally (e.g. `maven-metadata-central.xml`, `maven-metadata-local.xml`) so Maven can compare. The `<snapshots><updatePolicy>` governs how often Maven refetches this file. Corruption or staleness here is a classic cause of snapshot resolution bugs; `-U` forces a refresh.
code
xml · 17 lines<metadata>
<groupId>com.acme</groupId>
<artifactId>lib</artifactId>
<version>1.0-SNAPSHOT</version>
<versioning>
<snapshot>
<timestamp>20240115.103045</timestamp>
<buildNumber>7</buildNumber>
</snapshot>
<snapshotVersions>
<snapshotVersion>
<extension>jar</extension>
<value>1.0-20240115.103045-7</value>
</snapshotVersion>
</snapshotVersions>
</versioning>
</metadata>go deeper
It's an index file listing available versions.
Know it maps 1.0-SNAPSHOT to a concrete timestamped build.
Use it to debug snapshot staleness, updatePolicy, and per-repo metadata copies.
Reason about snapshot retention policies on the repository manager and metadata-corruption failure modes at scale.
## The problem it solves The repository layout (GAV -> path) is static: Maven can compute the path of a known release. But two things aren't knowable from a path alone: 1. **Which versions exist** for an artifact. 2. **For a SNAPSHOT, which exact build is newest** — because each deployed snapshot gets a unique timestamped filename. `maven-metadata.xml` is the index that answers these. ## Two flavours / locations - **Group/artifact level** (`groupId/artifactId/maven-metadata.xml`): lists `<versioning>` with `<latest>`, `<release>`, and `<versions>`. - **Version level for snapshots** (`groupId/artifactId/1.0-SNAPSHOT/maven-metadata.xml`): contains `<snapshot>` with `<timestamp>` and `<buildNumber>`, and `<snapshotVersions>` mapping classifier/extension to the concrete value. ## Snapshot resolution in practice When you depend on `com.acme:lib:1.0-SNAPSHOT`, a shared remote may hold many timestamped builds: `lib-1.0-20240115.090000-5.jar`, `...-6.jar`, etc. Maven reads the version-level `maven-metadata.xml` to learn the latest (`timestamp` + `buildNumber`) and downloads that specific file. The logical name stays `1.0-SNAPSHOT`. ```xml <metadata> <groupId>com.acme</groupId> <artifactId>lib</artifactId> <version>1.0-SNAPSHOT</version> <versioning> <snapshot> <timestamp>20240115.103045</timestamp> <buildNumber>7</buildNumber> </snapshot> <lastUpdated>20240115103045</lastUpdated> <snapshotVersions> <snapshotVersion> <extension>jar</extension> <value>1.0-20240115.103045-7</value> <updated>20240115103045</updated> </snapshotVersion> </snapshotVersions> </versioning> </metadata> ``` ## Local vs remote copies Maven keeps per-repository copies in the local cache, suffixed by repo id: `maven-metadata-central.xml`, `maven-metadata-local.xml`, etc. It compares these against the remote (subject to `updatePolicy`) to decide whether a newer snapshot exists. ## Refresh policy The `<repository><snapshots><updatePolicy>` value (`daily` default, or `always`/`never`/`interval:NN`) controls how often the metadata is refetched. `-U` forces a refresh now. Stale or corrupt metadata is a leading cause of "my build won't pick up the new snapshot" — deleting the cached metadata or using `-U` resolves it. ## Note on releases Releases are immutable, so version-level metadata is mainly relevant to snapshots; the group/artifact-level metadata still tracks the list of release versions (used by tools and range resolution).
- Why do deployed snapshots have timestamped filenames instead of all being literally 1.0-SNAPSHOT.jar?So a shared remote can retain multiple builds without overwriting; maven-metadata.xml maps the logical 1.0-SNAPSHOT to the newest timestamped file via timestamp+buildNumber.
- Where does Maven keep its view of remote metadata locally and why suffix it?In the local cache as maven-metadata-<repoId>.xml; the repo-id suffix lets Maven track metadata per source repository independently and compare them.
saying these in an interview costs you the question
- Saying maven-metadata.xml stores the actual bytecode/classes.
- Believing every snapshot deploy overwrites a single 1.0-SNAPSHOT.jar on the remote (timestamped uniqueness is the default).
- Confusing version-level snapshot metadata with the group/artifact version-list metadata.