ascheman opened a new issue, #2017:
URL: https://github.com/apache/maven-resolver/issues/2017

   # Affected version
   
   Maven Resolver 2.0.x (default changed in the 2.0 line; verified with 2.0.13 
and 2.0.20).
   Resolver 1.9.x is unaffected. Surfaced via Maven 3.10.0-rc-1 (bundles 
2.0.20) and Maven
   4.0.0-rc-5 (bundles 2.0.13); the current Maven `maven-4.0.x` and `master` 
branches ship
   resolver 2.0.x as well.
   
   # Bug description
   
   ## Summary
   
   Since Resolver 2.0, the **default named-lock factory is `file-lock`**
   (`DefaultNamedLockFactorySelector.DEFAULT_FACTORY_NAME = 
FileLockNamedLockFactory.NAME`),
   whereas 1.9.x effectively used in-memory locks. `file-lock` writes a 
`.locks` directory
   **inside the local repository base directory** 
(`BasedirNameMapper.DEFAULT_LOCKS_DIR = ".locks"`).
   
   Two consequences follow for any consumer (e.g. Maven), on a plain 
resolve/install:
   
   1. A `.locks` directory now appears in the local repository on **every OS** 
(empty on
      POSIX, populated on Windows).
   2. On **Windows** the 0-byte lock files are not cleaned up and remain. When 
the local
      repository is also used as a deploy/staging tree (as Sonatype's 
third-party
      `central-publishing-maven-plugin` does under `target/`), those `.locks` 
files get bundled
      and the Central Portal rejects the bundle (a `.locks` entry has no 
`.pom`).
   
   With resolver 1.9.x (Maven 3.9.x) no lock files were produced at all. So 
this is a behavior
   change introduced by the 2.0 default.
   
   Reported downstream on [email protected]:
   https://lists.apache.org/thread/1trdtdct2glycrzqo6xhbryns5o5pxno
   
   ## Root cause
   
   **1. `file-lock` is the 2.0 default; the `.locks` dir lives inside the local 
repo.**
   
`maven-resolver-impl/.../internal/impl/named/DefaultNamedLockFactorySelector.java`:
   
   ```java
   public static final String DEFAULT_FACTORY_NAME = 
FileLockNamedLockFactory.NAME; // "file-lock"
   ```
   
   
`maven-resolver-impl/.../internal/impl/synccontext/named/BasedirNameMapper.java`:
   
   ```java
   public static final String DEFAULT_LOCKS_DIR = ".locks";
   ```
   
   The base directory defaults to the local repository root, so the lock files 
are written into
   the very tree that consumers may treat as content. 
`DefaultNamedLockFactorySelector` did not
   exist in 1.9.x, whose default was in-memory — consistent with 1.9.x 
producing no `.locks`.
   
   Note: Maven's shipped distribution does **not** override this back — its
   `apache-maven/src/assembly/maven/conf/maven-system.properties` sets no
   `aether.syncContext.named.factory` on `master`, `maven-4.0.x` or 3.10.x. (A 
`rwlock-local`
   override exists only as a maven-cli test fixture, not in the distribution.) 
So the resolver
   default is what users get.
   
   **2. The files are left behind only on Windows.**
   `maven-resolver-named-locks/.../providers/FileLockNamedLockFactory.java`:
   
   ```java
   private static final boolean IS_WINDOWS =
       System.getProperty("os.name", "unknown").startsWith("Windows");
   
   private static final boolean DELETE_LOCK_FILES =
       Boolean.parseBoolean(System.getProperty(
           "aether.named.file-lock.deleteLockFiles", 
Boolean.toString(!IS_WINDOWS)));
   ```
   
   - **Linux/macOS:** the lock file is opened with 
`StandardOpenOption.DELETE_ON_CLOSE` and
     removed on close — the `.locks` directory ends up empty.
   - **Windows:** `DELETE_LOCK_FILES` defaults to `false` (a deliberate tweak, 
since
     `DELETE_ON_CLOSE` causes concurrency issues on Windows) → the 0-byte 
`.locks` files remain.
   
   So the *default change* (`.locks` created inside the local repo) is 
OS-independent; the
   *leftover files* that break deploy staging are the Windows-specific 
consequence.
   
   ## Verification (end-to-end, no third-party plugin)
   
   A plain `mvn install` in default configuration into an isolated local 
repository creates the
   `.locks` directory — proving it is the resolver default at work, no plugin 
involved. A core IT
   (`MavenITghFileLockDefaultLocksTest`) asserts a default run creates **no** 
`.locks` directory;
   it fails on every released Maven that bundles resolver 2.0. CI matrix — all 
six jobs fail at
   the assertion:
   
   | | ubuntu | windows | macOS |
   |---|---|---|---|
   | Maven 3.10.0-rc-1 (resolver 2.0.20) | Failures: 1 | Failures: 1 | 
Failures: 1 |
   | Maven 4.0.0-rc-5 (resolver 2.0.13) | Failures: 1 | Failures: 1 | Failures: 
1 |
   
   CI run: 
https://github.com/aschemaven/maven-integration-testing/actions/runs/30391734694
   
   The Windows leftover files also reproduce on Linux/macOS by forcing the 
Windows path with
   `-Daether.named.file-lock.deleteLockFiles=false` (168 leftover 0-byte files 
in a small build).
   
   ## Workaround for consumers
   
   ```
   -Daether.syncContext.named.factory=rwlock-local
   ```
   
   ## Suggested direction (maintainers decide)
   
   Options, roughly in order of "fixes the root cause":
   
   1. Do not place `file-lock` lock files **inside the local repository** — use 
a location that
      is never treated as content (e.g. a temp/state dir), so consumers can't 
bundle them.
   2. Clean up the lock files on Windows too (or make `.locks` never contain 
deployable-looking
      entries).
   3. Reconsider `file-lock` as the default for the common single-process case.
   
   (A consumer-side mitigation — Maven defaulting 
`aether.syncContext.named.factory=rwlock-local`
   — treats the symptom, not the cause.)
   
   ## Environment
   
   - Maven Resolver `2.0.13` and `2.0.20` (affected); `1.9.27` unaffected.
   - Consumers observed: Maven `3.10.0-rc-1`, `4.0.0-rc-5`, and current 
`maven-4.0.x` / `master`.
   - OS: `.locks` directory created on all of Linux/macOS/Windows; leftover 
`.locks` files on
     Windows (the fatal case for deploy staging).
   - Downstream where it surfaced: 
`org.sonatype.central:central-publishing-maven-plugin:0.11.0`
     publishing to `central.sonatype.com`.
   


-- 
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