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 9f10b0115..b35a985e0 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 @@ -36,10 +36,16 @@ import java.nio.file.StandardOpenOption; import java.util.Map; import java.util.Properties; +import java.util.concurrent.TimeUnit; +import org.eclipse.aether.named.NamedLock; +import org.eclipse.aether.named.NamedLockKey; +import org.eclipse.aether.named.providers.FileLockNamedLockFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import static java.util.concurrent.TimeUnit.SECONDS; + /** * Manages access to a properties file. *

@@ -52,6 +58,8 @@ @Named public final class DefaultTrackingFileManager implements TrackingFileManager { private static final Logger LOGGER = LoggerFactory.getLogger(DefaultTrackingFileManager.class); + private static final FileLockNamedLockFactory FILE_LOCK_FACTORY = new FileLockNamedLockFactory(); + private static final long FILE_LOCK_TIMEOUT = 10L; @Deprecated @Override @@ -62,18 +70,24 @@ public Properties read(File file) { @Override public Properties read(Path path) { if (Files.isReadable(path)) { - synchronized (mutex(path)) { - try (FileChannel fileChannel = FileChannel.open(path, StandardOpenOption.READ); - FileLock unused = fileLock(fileChannel, true)) { - Properties props = new Properties(); - props.load(Channels.newInputStream(fileChannel)); - return props; - } catch (NoSuchFileException e) { - LOGGER.debug("No such file to read {}: {}", path, e.getMessage()); - } catch (IOException e) { - LOGGER.warn("Failed to read tracking file '{}'", path, e); - throw new UncheckedIOException(e); + final String lockUri = lockUri(path); + try (NamedLock lock = FILE_LOCK_FACTORY.getLock(NamedLockKey.of(lockUri, lockUri))) { + if (lock.lockExclusively(FILE_LOCK_TIMEOUT, SECONDS)) { + try (FileChannel fileChannel = FileChannel.open(path, StandardOpenOption.READ)) { + Properties props = new Properties(); + props.load(Channels.newInputStream(fileChannel)); + return props; + } catch (NoSuchFileException e) { + LOGGER.debug("No such file to read {}: {}", path, e.getMessage()); + } catch (IOException e) { + LOGGER.warn("Failed to read tracking file '{}'", path, e); + throw new UncheckedIOException(e); + } finally { + lock.unlock(); + } } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); } } return null; @@ -164,6 +178,10 @@ private static Object mutex(Path path) { return canonicalPath(path).toString().intern(); } + private static String lockUri(Path path) { + return canonicalPath(path).toUri().toString(); + } + /** * Tries the best it can to figure out actual file the workload is about, while resolving cases like symlinked * local repository etc. diff --git a/maven-resolver-named-locks/src/main/java/org/eclipse/aether/named/NamedLock.java b/maven-resolver-named-locks/src/main/java/org/eclipse/aether/named/NamedLock.java index 4f5b3d2af..27866abff 100644 --- a/maven-resolver-named-locks/src/main/java/org/eclipse/aether/named/NamedLock.java +++ b/maven-resolver-named-locks/src/main/java/org/eclipse/aether/named/NamedLock.java @@ -29,8 +29,7 @@ * if (lock.lockExclusively(10L, Timeunit.SECONDS)) { * try { * ... exclusive access to "resourceName" resource gained here - * } - * finally { + * } finally { * lock.unlock(); * } * }