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]

Reply via email to