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]