This is an automated email from the ASF dual-hosted git repository.
cstamas pushed a commit to branch maven-resolver-1.9.x
in repository https://gitbox.apache.org/repos/asf/maven-resolver.git
The following commit(s) were added to refs/heads/maven-resolver-1.9.x by this
push:
new 7b41467ce Sync TrackingFileManager with 2.x (#1802)
7b41467ce is described below
commit 7b41467ce4318a2e14b8ca087e32118b49dc01ab
Author: Tamas Cservenak <[email protected]>
AuthorDate: Fri Feb 20 13:19:38 2026 +0100
Sync TrackingFileManager with 2.x (#1802)
Backport all the changes from 2.x to 1.x
---
.../internal/impl/DefaultTrackingFileManager.java | 37 +++++++++++++++++++---
1 file changed, 33 insertions(+), 4 deletions(-)
diff --git
a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultTrackingFileManager.java
b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultTrackingFileManager.java
index 7076f38f7..83785ef47 100644
---
a/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultTrackingFileManager.java
+++
b/maven-resolver-impl/src/main/java/org/eclipse/aether/internal/impl/DefaultTrackingFileManager.java
@@ -140,10 +140,28 @@ public final class DefaultTrackingFileManager implements
TrackingFileManager {
return false;
}
- private Object mutex(Path path) {
+ /**
+ * This method creates a "mutex" object to synchronize on thread level,
within same JVM, to prevent multiple
+ * threads from trying to lock the same file at the same time. Threads
concurrently working on different files
+ * are okay, as after syncing on mutex, they operate with FS locking, that
goal is to synchronize with possible
+ * other Maven processes, and not with other threads in this JVM.
+ */
+ private static Object mutex(Path path) {
// The interned string of path is (mis)used as mutex, to exclude
different threads going for same file,
// as JVM file locking happens on JVM not on Thread level. This is how
original code did it ¯\_(ツ)_/¯
- return path.toAbsolutePath().normalize().toString().intern();
+ return canonicalPath(path).toString().intern();
+ }
+
+ /**
+ * Tries the best it can to figure out actual file the workload is about,
while resolving cases like symlinked
+ * local repository etc.
+ */
+ private static Path canonicalPath(Path path) {
+ try {
+ return path.toRealPath();
+ } catch (IOException e) {
+ return canonicalPath(path.getParent()).resolve(path.getFileName());
+ }
}
private FileLock fileLock(FileChannel channel, boolean shared) throws
IOException {
@@ -152,9 +170,20 @@ public final class DefaultTrackingFileManager implements
TrackingFileManager {
try {
lock = channel.lock(0, Long.MAX_VALUE, shared);
break;
- } catch (OverlappingFileLockException e) {
+ } catch (OverlappingFileLockException | IOException e) {
+ // For Unix process sun.nio.ch.UnixFileDispatcherImpl.lock0()
is a native method that can throw
+ // IOException with message "Resource deadlock avoided"
+ // the system call level is involving fcntl() or flock()
+ // If the kernel detects that granting the lock would result
in a deadlock
+ // (where two processes are waiting for each other to release
locks which can happen when two processes
+ // are trying to lock the same file),
+ // it returns an EDEADLK error, which Java throws as an
IOException.
+ // Read another comment from
+ //
https://github.com/bdeployteam/bdeploy/blob/7c04e7228d6d48b8990e6703a8d476e21024c639/bhive/src/main/java/io/bdeploy/bhive/objects/LockableDatabase.java#L57
+ // Note (cstamas): seems this MAY also happen where there is
ONE process but performs locking on same
+ // file from multiple threads, as Linux kernel performs lock
detection on process level.
if (attempts <= 0) {
- throw new IOException(e);
+ throw (e instanceof IOException) ? (IOException) e : new
IOException(e);
}
try {
Thread.sleep(50L);