kec opened a new issue, #13295:
URL: https://github.com/apache/maven/issues/13295
### Affected version
4.0.0-rc-7 (also on `master`: `MavenSnapshotMetadata.getKey` is unchanged).
3.9.11 is not affected.
### Bug description
When a snapshot is deployed onto a repository whose version-level
`maven-metadata.xml` lists a no-classifier artifact **without** a
`<classifier>` element, Maven 4 keeps that stale entry and adds a new one next
to it. Maven 3 writes metadata that way, and so do repository managers that
regenerate metadata, such as Nexus Repository 3. The file ends up with two
`pom` (or `jar`) entries: the new build, with an empty
`<classifier></classifier>`, and the previous build, which should have been
replaced. Maven 3.9.11 replaces it correctly.
#### Reproduction (no repository manager involved)
1. Serve an empty directory over HTTP with PUT support, and point a plain
`modelVersion 4.0.0` POM project (`test.repro:repro:1-SNAPSHOT`, packaging
`pom`) at it as `snapshotRepository`.
2. Seed `test/repro/repro/1-SNAPSHOT/maven-metadata.xml` (with matching
`.sha1` and `.md5`) as:
```xml
<metadata modelVersion="1.1.0">
<groupId>test.repro</groupId>
<artifactId>repro</artifactId>
<versioning>
<lastUpdated>20260901000000</lastUpdated>
<snapshot><timestamp>20260901.000000</timestamp><buildNumber>1</buildNumber></snapshot>
<snapshotVersions>
<snapshotVersion>
<extension>pom</extension>
<value>1-20260901.000000-1</value>
<updated>20260901000000</updated>
</snapshotVersion>
</snapshotVersions>
</versioning>
<version>1-SNAPSHOT</version>
</metadata>
```
3. Run `mvn deploy` once.
**Maven 3.9.11**: one entry, `pom` → `1-<ts>-2`. The stale entry is replaced.
**Maven 4.0.0-rc-7**: three entries:
```
<classifier>build</classifier> <extension>pom</extension>
<value>1-<ts>-2</value>
<classifier></classifier> <extension>pom</extension>
<value>1-<ts>-2</value>
<extension>pom</extension>
<value>1-20260901.000000-1</value> ← stale
```
#### Cause
`MavenSnapshotMetadata.getKey` builds the merge key with string
concatenation:
```java
protected String getKey(String classifier, String extension) {
return classifier + ':' + extension;
}
```
A new artifact's classifier is `""`, so its key is `":pom"`. An entry read
from metadata without a `<classifier>` element has a `null` classifier, so its
key is `"null:pom"`. The keys never match, and `RemoteSnapshotMetadata.merge`
keeps the recessive entry (`if (!versions.containsKey(key))`).
Relatedly, the writer emits `<classifier></classifier>` for no-classifier
artifacts, where Maven 3 omitted the element. A reader that treats absent and
empty differently now sees two shapes for the same thing.
#### Suggested fix
Treat `null` and `""` as the same classifier in `getKey`, for example
`(classifier == null ? "" : classifier) + ':' + extension`. Consider not
writing an empty `<classifier>` element.
#### Impact
Stale `snapshotVersion` entries accumulate whenever metadata passes through
another writer. That includes any Nexus-hosted snapshot repository, because
Nexus regenerates version-level metadata in the Maven 3 shape. A consumer
resolving by classifier and extension can pick the stale timestamped build.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]