diff --git a/tycho-api/src/main/java/org/eclipse/tycho/FileLockService.java b/tycho-api/src/main/java/org/eclipse/tycho/FileLockService.java
index 21e525627a..4aa33f92c3 100644
--- a/tycho-api/src/main/java/org/eclipse/tycho/FileLockService.java
+++ b/tycho-api/src/main/java/org/eclipse/tycho/FileLockService.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011 SAP AG and others.
+ * Copyright (c) 2011, 2023 SAP AG and others.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
@@ -13,6 +13,7 @@
package org.eclipse.tycho;
+import java.io.Closeable;
import java.io.File;
/**
@@ -21,10 +22,25 @@
public interface FileLockService {
/**
- * Get a locker object which can be used to protect read/write access from multiple processes on
- * the given file. Locking is advisory only, i.e. all processes must use the same locking
- * mechanism.
+ * Locks the given file to protect read/write access from multiple processes on it. Locking is
+ * advisory only, i.e. all processes must use the same locking mechanism.
+ *
+ * This is equivalent to {@link #lock(File, long)} with a timeout argument of 10 seconds.
+ *
*/
- public FileLocker getFileLocker(File file);
+ default Closeable lock(File file) {
+ return lock(file, 10000L);
+ }
+ /**
+ * Locks the given file to protect read/write access from multiple processes on it. Locking is
+ * advisory only, i.e. all processes must use the same locking mechanism.
+ */
+ Closeable lock(File file, long timeout);
+
+ /**
+ * Locks the given file for this JVM to protect read/write access from multiple threads in this
+ * JVM on it.
+ */
+ Closeable lockVirtually(File file);
}
diff --git a/tycho-core/src/main/java/org/eclipse/tycho/core/locking/FileLockServiceImpl.java b/tycho-core/src/main/java/org/eclipse/tycho/core/locking/FileLockServiceImpl.java
index 270afe2d9f..51991a83a8 100644
--- a/tycho-core/src/main/java/org/eclipse/tycho/core/locking/FileLockServiceImpl.java
+++ b/tycho-core/src/main/java/org/eclipse/tycho/core/locking/FileLockServiceImpl.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011, 2020 SAP AG and others.
+ * Copyright (c) 2011, 2023 SAP AG and others.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
@@ -13,28 +13,62 @@
package org.eclipse.tycho.core.locking;
+import java.io.Closeable;
import java.io.File;
import java.io.IOException;
+import java.nio.file.Path;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
import org.codehaus.plexus.component.annotations.Component;
import org.eclipse.tycho.FileLockService;
+import org.eclipse.tycho.LockTimeoutException;
@Component(role = FileLockService.class)
public class FileLockServiceImpl implements FileLockService {
+ record FileLocks(FileLockerImpl fileLocker, Lock vmLock) {
+ }
+
+ private final Map lockers = new ConcurrentHashMap<>();
- private final Map lockers = new ConcurrentHashMap<>();
+ @Override
+ public Closeable lock(File file, long timeout) {
+ FileLocks locks = getFileLocker(file.toPath());
+ FileLockerImpl locker = locks.fileLocker();
+ try {
+ if (!locks.vmLock().tryLock(timeout, TimeUnit.MILLISECONDS)) {
+ throw new LockTimeoutException("lock timeout: Could not acquire lock on file " + locker.lockMarkerFile
+ + " for " + timeout + " msec");
+ }
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new LockTimeoutException("Interrupted", e);
+ }
+ locker.lock(timeout);
+ return () -> {
+ locks.fileLocker().release();
+ locks.vmLock().unlock();
+ };
+ }
@Override
- public FileLockerImpl getFileLocker(File file) {
- String key;
+ public Closeable lockVirtually(File file) {
+ FileLocks locks = getFileLocker(file.toPath());
+ locks.vmLock().lock();
+ return locks.vmLock()::unlock;
+ }
+
+ FileLocks getFileLocker(Path file) {
+ Path key;
try {
- key = file.getCanonicalPath();
+ key = file.toRealPath();
} catch (IOException e) {
- key = file.getAbsolutePath();
+ key = file.toAbsolutePath().normalize();
}
- return lockers.computeIfAbsent(key, k -> new FileLockerImpl(file));
+ return lockers.computeIfAbsent(key, f -> new FileLocks(new FileLockerImpl(f), new ReentrantLock()));
}
}
diff --git a/tycho-core/src/main/java/org/eclipse/tycho/core/locking/FileLockerImpl.java b/tycho-core/src/main/java/org/eclipse/tycho/core/locking/FileLockerImpl.java
index 7fcb2a07ff..216a1d480d 100644
--- a/tycho-core/src/main/java/org/eclipse/tycho/core/locking/FileLockerImpl.java
+++ b/tycho-core/src/main/java/org/eclipse/tycho/core/locking/FileLockerImpl.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011 SAP AG and others.
+ * Copyright (c) 2011, 2023 SAP AG and others.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
@@ -15,60 +15,46 @@
import java.io.File;
import java.io.IOException;
-import java.net.MalformedURLException;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
+import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
-import org.eclipse.tycho.FileLocker;
import org.eclipse.tycho.LockTimeoutException;
-public class FileLockerImpl implements FileLocker {
+public class FileLockerImpl {
private static final String LOCKFILE_SUFFIX = ".tycholock";
- final File lockMarkerFile;
+ final Path lockMarkerFile;
private FileLock lock;
- private File file;
+ private Path file;
- public FileLockerImpl(File file) {
- this.file = file;
+ FileLockerImpl(Path file) {
+ this.file = file.toAbsolutePath().normalize();
+ this.lockMarkerFile = Files.isDirectory(this.file) //
+ ? this.file.resolve(LOCKFILE_SUFFIX)
+ : this.file.getParent().resolve(this.file.getFileName() + LOCKFILE_SUFFIX);
try {
- if (file.isDirectory()) {
- this.lockMarkerFile = new File(file, LOCKFILE_SUFFIX).getCanonicalFile();
- } else {
- this.lockMarkerFile = new File(file.getParentFile(), file.getName() + LOCKFILE_SUFFIX)
- .getCanonicalFile();
+ if (Files.isDirectory(lockMarkerFile)) {
+ throw new IllegalStateException(
+ "Lock marker file " + lockMarkerFile + " already exists and is a directory");
}
- if (lockMarkerFile.isDirectory()) {
- throw new RuntimeException("Lock marker file " + lockMarkerFile + " already exists and is a directory");
- }
- File parentDir = lockMarkerFile.getParentFile();
- if (!parentDir.mkdirs() && !parentDir.isDirectory()) {
- throw new RuntimeException("Could not create parent directory " + parentDir + " of lock marker file");
- }
- } catch (MalformedURLException e) {
- throw new RuntimeException(e);
+ Files.createDirectories(lockMarkerFile.getParent());
} catch (IOException e) {
- throw new RuntimeException(e);
+ throw new IllegalStateException(e);
}
}
- @Override
- public void lock() {
- lock(10000L);
- }
-
- @Override
- public void lock(long timeout) {
+ void lock(long timeout) {
if (timeout < 0) {
throw new IllegalArgumentException("timeout must not be negative");
}
if (lock != null) {
- throw new LockTimeoutException("already locked file " + file.getAbsolutePath());
+ throw new LockTimeoutException("already locked file " + file);
}
lock = aquireLock(timeout);
@@ -81,8 +67,7 @@ private FileLock aquireLock(long timeout) {
for (long i = 0; i < maxTries; i++) {
try {
if (channel == null) {
- Path path = lockMarkerFile.toPath();
- channel = FileChannel.open(path, StandardOpenOption.WRITE, StandardOpenOption.CREATE);
+ channel = FileChannel.open(lockMarkerFile, StandardOpenOption.WRITE, StandardOpenOption.CREATE);
}
FileLock fileLock = channel.tryLock();
if (fileLock != null) {
@@ -105,26 +90,22 @@ private FileLock aquireLock(long timeout) {
channel = null;
}
}
- throw new LockTimeoutException("lock timeout: Could not acquire lock on file "
- + lockMarkerFile.getAbsolutePath() + " for " + timeout + " msec");
+ throw new LockTimeoutException(
+ "lock timeout: Could not acquire lock on file " + lockMarkerFile + " for " + timeout + " msec");
}
- @Override
- public synchronized void release() {
+ synchronized void release() {
if (lock != null) {
try {
lock.acquiredBy().close();
} catch (Exception e) {
}
lock = null;
- if (!lockMarkerFile.delete()) {
- lockMarkerFile.deleteOnExit();
+ File lockFile = lockMarkerFile.toFile();
+ if (!lockFile.delete()) {
+ lockFile.deleteOnExit();
}
}
}
- public synchronized boolean isLocked() {
- return lock != null;
- }
-
}
diff --git a/tycho-core/src/main/java/org/eclipse/tycho/core/osgitools/DefaultBundleReader.java b/tycho-core/src/main/java/org/eclipse/tycho/core/osgitools/DefaultBundleReader.java
index 841247215c..7542ceb8ef 100644
--- a/tycho-core/src/main/java/org/eclipse/tycho/core/osgitools/DefaultBundleReader.java
+++ b/tycho-core/src/main/java/org/eclipse/tycho/core/osgitools/DefaultBundleReader.java
@@ -36,7 +36,6 @@
import org.codehaus.plexus.component.annotations.Requirement;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.eclipse.tycho.FileLockService;
-import org.eclipse.tycho.FileLocker;
import org.eclipse.tycho.TychoConstants;
@Component(role = BundleReader.class)
@@ -189,9 +188,7 @@ public File getEntry(File bundleLocation, String path) {
throw new RuntimeException("can't get canonical path for " + cacheFile, e);
}
result = extractedFiles.computeIfAbsent(cacheKey, nil -> {
- FileLocker locker = fileLockService.getFileLocker(outputDirectory);
- locker.lock(LOCK_TIMEOUT);
- try {
+ try (var locked = fileLockService.lock(outputDirectory, LOCK_TIMEOUT)) {
extractZipEntries(bundleLocation, path, outputDirectory);
if (cacheFile.exists()) {
return Optional.of(cacheFile);
@@ -200,8 +197,6 @@ public File getEntry(File bundleLocation, String path) {
} catch (IOException e) {
throw new RuntimeException(
"Can't extract '" + path + "' from " + bundleLocation + " to " + outputDirectory, e);
- } finally {
- locker.release();
}
});
}
diff --git a/tycho-core/src/main/java/org/eclipse/tycho/p2/repository/FileBasedTychoRepositoryIndex.java b/tycho-core/src/main/java/org/eclipse/tycho/p2/repository/FileBasedTychoRepositoryIndex.java
index a4f3814b39..a88db13366 100644
--- a/tycho-core/src/main/java/org/eclipse/tycho/p2/repository/FileBasedTychoRepositoryIndex.java
+++ b/tycho-core/src/main/java/org/eclipse/tycho/p2/repository/FileBasedTychoRepositoryIndex.java
@@ -30,7 +30,6 @@
import java.util.Set;
import org.eclipse.tycho.FileLockService;
-import org.eclipse.tycho.FileLocker;
import org.eclipse.tycho.core.shared.MavenContext;
import org.eclipse.tycho.core.shared.MavenLogger;
@@ -47,7 +46,7 @@ public class FileBasedTychoRepositoryIndex implements TychoRepositoryIndex {
private final File indexFile;
private final MavenLogger logger;
- private FileLocker fileLocker;
+ private final FileLockService fileLockService;
private Set addedGavs = new HashSet<>();
private Set removedGavs = new HashSet<>();
@@ -58,28 +57,17 @@ private FileBasedTychoRepositoryIndex(File indexFile, FileLockService fileLockSe
super();
this.indexFile = indexFile;
this.mavenContext = mavenContext;
- this.fileLocker = fileLockService.getFileLocker(indexFile);
+ this.fileLockService = fileLockService;
this.logger = mavenContext.getLogger();
if (indexFile.isFile()) {
- lock();
- try {
+ try (var locked = fileLockService.lock(indexFile)) {
gavs = read(new FileInputStream(indexFile));
} catch (IOException e) {
throw new RuntimeException(e);
- } finally {
- unlock();
}
}
}
- private void lock() {
- fileLocker.lock();
- }
-
- private void unlock() {
- fileLocker.release();
- }
-
@Override
public MavenContext getMavenContext() {
return mavenContext;
@@ -118,8 +106,7 @@ public synchronized void save() throws IOException {
if (!parentDir.isDirectory()) {
parentDir.mkdirs();
}
- lock();
- try {
+ try (var locked = fileLockService.lock(indexFile)) {
reconcile();
// minimize time window for corrupting the file by first writing to a temp file, then moving it
File tempFile = File.createTempFile("index", "tmp", indexFile.getParentFile());
@@ -128,8 +115,6 @@ public synchronized void save() throws IOException {
indexFile.delete();
}
tempFile.renameTo(indexFile);
- } finally {
- unlock();
}
}
diff --git a/tycho-core/src/test/java/org/eclipse/tycho/core/locking/FileLockServiceTest.java b/tycho-core/src/test/java/org/eclipse/tycho/core/locking/FileLockServiceTest.java
index 67d8672c32..7a3ca09bbd 100644
--- a/tycho-core/src/test/java/org/eclipse/tycho/core/locking/FileLockServiceTest.java
+++ b/tycho-core/src/test/java/org/eclipse/tycho/core/locking/FileLockServiceTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011, 2022 SAP AG and others.
+ * Copyright (c) 2011, 2023 SAP AG and others.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
@@ -20,9 +20,14 @@
import java.io.File;
import java.io.IOException;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileLock;
+import java.nio.channels.OverlappingFileLockException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
import java.util.Random;
-import org.eclipse.tycho.FileLocker;
import org.eclipse.tycho.LockTimeoutException;
import org.junit.Before;
import org.junit.Rule;
@@ -42,90 +47,60 @@ public void setup() {
@Test
public void testIsLocked() throws IOException {
- FileLockerImpl fileLocker = subject.getFileLocker(newTestFile());
- fileLocker.lock();
- try {
- assertTrue(fileLocker.isLocked());
- } finally {
- fileLocker.release();
- assertFalse(fileLocker.isLocked());
+ File file = newTestFile();
+ try (var locked = subject.lock(file)) {
+ assertTrue(isLocked(file));
}
+ assertFalse(isLocked(file));
}
@Test(expected = IllegalArgumentException.class)
public void testNegativeTimeout() throws IOException {
- FileLocker fileLocker = subject.getFileLocker(newTestFile());
- fileLocker.lock(-1L);
+ subject.lock(newTestFile(), -1L);
}
@Test
public void testLockDirectory() throws IOException {
File testDir = tempFolder.newFolder("test");
- FileLockerImpl fileLocker = subject.getFileLocker(testDir);
- fileLocker.lock();
- try {
- assertTrue(fileLocker.isLocked());
- assertEquals(new File(testDir, ".tycholock").getCanonicalPath(),
- fileLocker.lockMarkerFile.getCanonicalPath());
- } finally {
- fileLocker.release();
- }
- }
-
- @Test
- public void testLockReentranceSameLocker() throws IOException {
- FileLocker fileLocker = subject.getFileLocker(newTestFile());
- fileLocker.lock();
- try {
- // locks are not re-entrant
- fileLocker.lock(0L);
- fail("lock already held by same VM but could be acquired a second time");
- } catch (LockTimeoutException e) {
- // expected
- } finally {
- fileLocker.release();
+ Path lockFile = getLockMarkerFile(testDir);
+ try (var locked = subject.lock(testDir)) {
+ assertTrue(isLocked(testDir));
+ assertEquals(new File(testDir, ".tycholock").getCanonicalPath(), lockFile.toRealPath().toString());
}
}
@Test
public void testReuseLockerObject() throws IOException {
- FileLockerImpl fileLocker = subject.getFileLocker(newTestFile());
- lockAndRelease(fileLocker);
- lockAndRelease(fileLocker);
+ File file = newTestFile();
+ lockAndRelease(file);
+ lockAndRelease(file);
}
- private void lockAndRelease(FileLockerImpl fileLocker) {
- assertFalse(fileLocker.isLocked());
- fileLocker.lock();
- assertTrue(fileLocker.isLocked());
- fileLocker.release();
- assertFalse(fileLocker.isLocked());
+ private void lockAndRelease(File file) throws IOException {
+ assertFalse(isLocked(file));
+ try (var locked = subject.lock(file)) {
+ assertTrue(isLocked(file));
+ }
+ assertFalse(isLocked(file));
}
@Test
public void testLockReentranceDifferentLocker() throws IOException {
final File testFile = newTestFile();
- FileLocker fileLocker1 = subject.getFileLocker(testFile);
- FileLocker fileLocker2 = subject.getFileLocker(testFile);
- fileLocker1.lock();
- try {
- fileLocker2.lock(0L);
+ try (var locked = subject.lock(testFile)) {
+ subject.lock(testFile, 0L);
fail("lock already held by same VM but could be acquired a second time");
} catch (LockTimeoutException e) {
// expected
- } finally {
- fileLocker1.release();
}
}
@Test
public void testLockedByOtherProcess() throws Exception {
File testFile = newTestFile();
- FileLocker locker = subject.getFileLocker(testFile);
LockProcess lockProcess = new LockProcess(testFile, 200L);
lockProcess.lockFileInForkedProcess();
- try {
- locker.lock(0L);
+ try (var locked = subject.lock(testFile, 0L)) {
fail("lock already held by other VM but could be acquired a second time");
} catch (LockTimeoutException e) {
// expected
@@ -136,49 +111,35 @@ public void testLockedByOtherProcess() throws Exception {
@Test
public void testTimeout() throws Exception {
File testFile = newTestFile();
- FileLocker locker = subject.getFileLocker(testFile);
long waitTime = 1000L;
LockProcess lockProcess = new LockProcess(testFile, waitTime);
long start = System.currentTimeMillis();
lockProcess.lockFileInForkedProcess();
- locker.lock(20000L);
- try {
+ try (var locked = subject.lock(testFile, 20000L)) {
long duration = System.currentTimeMillis() - start;
assertTrue(duration >= waitTime);
} finally {
lockProcess.cleanup();
- locker.release();
}
}
- @Test
- public void testRelease() throws Exception {
- FileLockerImpl locker = subject.getFileLocker(newTestFile());
- assertFalse(locker.isLocked());
- // releasing without holding the lock should do nothing
- locker.release();
- }
-
@Test
public void testMarkerFileDeletion() throws Exception {
- FileLockerImpl locker = subject.getFileLocker(newTestFile());
- locker.lock();
- assertTrue(locker.lockMarkerFile.isFile());
- locker.release();
- assertFalse(locker.lockMarkerFile.isFile());
+ File file = newTestFile();
+ Path lockFile = getLockMarkerFile(file);
+ try (var locked = subject.lock(file)) {
+ assertTrue(Files.isRegularFile(lockFile));
+ }
+ assertFalse(Files.isRegularFile(lockFile));
}
@Test
public void testURLEncoding() throws IOException {
File testFile = new File(tempFolder.getRoot(), "file with spaces" + new Random().nextInt());
File markerFile = new File(testFile.getAbsolutePath() + ".tycholock");
- FileLocker fileLocker = subject.getFileLocker(testFile);
assertFalse(markerFile.isFile());
- fileLocker.lock();
- try {
+ try (var locked = subject.lock(testFile)) {
assertTrue(markerFile.isFile());
- } finally {
- fileLocker.release();
}
}
@@ -187,4 +148,17 @@ private File newTestFile() throws IOException {
return testFile;
}
+ private Path getLockMarkerFile(File file) {
+ return subject.getFileLocker(file.toPath()).fileLocker().lockMarkerFile;
+ }
+
+ private boolean isLocked(File file) throws IOException {
+ try (var channel = FileChannel.open(getLockMarkerFile(file), StandardOpenOption.WRITE,
+ StandardOpenOption.CREATE); FileLock lock = channel.tryLock();) {
+ return lock == null;
+ } catch (OverlappingFileLockException e) {
+ return true;
+ }
+ }
+
}
diff --git a/tycho-its/src/test/java/org/eclipse/tycho/test/pomDependencyConsider/LocalMavenRepositoryTool.java b/tycho-its/src/test/java/org/eclipse/tycho/test/pomDependencyConsider/LocalMavenRepositoryTool.java
index 5e1be22158..1495af946a 100644
--- a/tycho-its/src/test/java/org/eclipse/tycho/test/pomDependencyConsider/LocalMavenRepositoryTool.java
+++ b/tycho-its/src/test/java/org/eclipse/tycho/test/pomDependencyConsider/LocalMavenRepositoryTool.java
@@ -27,7 +27,6 @@
import java.util.Set;
import org.eclipse.tycho.FileLockService;
-import org.eclipse.tycho.FileLocker;
import org.eclipse.tycho.test.util.EnvironmentUtil;
public class LocalMavenRepositoryTool {
@@ -59,12 +58,8 @@ public File getArtifactFile(String groupId, String artifactId, String version, S
public Set getArtifactIndexLines() throws IOException {
File indexFile = getArtifactIndexFile();
- FileLocker locker = fileLockService.getFileLocker(indexFile);
- locker.lock();
- try {
+ try (var locked = fileLockService.lock(indexFile)) {
return readLines(indexFile);
- } finally {
- locker.release();
}
}
@@ -95,14 +90,10 @@ public void removeLinesFromMetadataIndex(String... linesToBeRemoved) throws IOEx
private void filterLinesFromIndex(File indexFile, Set toBeRemoved)
throws FileNotFoundException, IOException {
- FileLocker locker = fileLockService.getFileLocker(indexFile);
- locker.lock();
- try {
+ try (var locked = fileLockService.lock(indexFile)) {
Set currentLines = readLines(indexFile);
currentLines.removeAll(toBeRemoved);
writeLines(indexFile, currentLines);
- } finally {
- locker.release();
}
}
diff --git a/tycho-p2-publisher-plugin/src/main/java/org/eclipse/tycho/plugins/p2/publisher/PublishProductMojo.java b/tycho-p2-publisher-plugin/src/main/java/org/eclipse/tycho/plugins/p2/publisher/PublishProductMojo.java
index ffba1a56ff..7b96432091 100644
--- a/tycho-p2-publisher-plugin/src/main/java/org/eclipse/tycho/plugins/p2/publisher/PublishProductMojo.java
+++ b/tycho-p2-publisher-plugin/src/main/java/org/eclipse/tycho/plugins/p2/publisher/PublishProductMojo.java
@@ -30,7 +30,11 @@
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
-import org.apache.maven.plugins.annotations.*;
+import org.apache.maven.plugins.annotations.Component;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.plugins.annotations.ResolutionScope;
import org.codehaus.plexus.archiver.ArchiverException;
import org.codehaus.plexus.archiver.UnArchiver;
import org.eclipse.equinox.p2.metadata.expression.IExpression;
@@ -43,7 +47,6 @@
import org.eclipse.tycho.ArtifactType;
import org.eclipse.tycho.DependencyArtifacts;
import org.eclipse.tycho.FileLockService;
-import org.eclipse.tycho.FileLocker;
import org.eclipse.tycho.Interpolator;
import org.eclipse.tycho.PackagingType;
import org.eclipse.tycho.PlatformPropertiesUtils;
@@ -207,19 +210,15 @@ private File getExpandedLauncherBinaries() throws MojoExecutionException, MojoFa
return unzipped.getAbsoluteFile();
}
try {
- FileLocker locker = fileLockService.getFileLocker(equinoxExecFeature);
- locker.lock();
- try {
+ try (var locked = fileLockService.lock(equinoxExecFeature)) {
// unzip now then:
unzipped.mkdirs();
deflater.setSourceFile(equinoxExecFeature);
deflater.setDestDirectory(unzipped);
deflater.extract();
return unzipped.getAbsoluteFile();
- } finally {
- locker.release();
}
- } catch (ArchiverException e) {
+ } catch (ArchiverException | IOException e) {
throw new MojoFailureException("Unable to unzip the equinox executable feature", e);
}
}
diff --git a/tycho-packaging-plugin/src/main/java/org/eclipse/tycho/packaging/FeatureXmlTransformer.java b/tycho-packaging-plugin/src/main/java/org/eclipse/tycho/packaging/FeatureXmlTransformer.java
index 4486197a25..ef56b2192e 100644
--- a/tycho-packaging-plugin/src/main/java/org/eclipse/tycho/packaging/FeatureXmlTransformer.java
+++ b/tycho-packaging-plugin/src/main/java/org/eclipse/tycho/packaging/FeatureXmlTransformer.java
@@ -15,6 +15,7 @@
import java.io.File;
import java.io.IOException;
+import java.util.Enumeration;
import java.util.Map;
import java.util.Objects;
import java.util.function.BinaryOperator;
@@ -31,7 +32,6 @@
import org.eclipse.tycho.ArtifactKey;
import org.eclipse.tycho.ArtifactType;
import org.eclipse.tycho.FileLockService;
-import org.eclipse.tycho.FileLocker;
import org.eclipse.tycho.IllegalArtifactReferenceException;
import org.eclipse.tycho.TargetPlatform;
import org.eclipse.tycho.model.Feature;
@@ -157,9 +157,7 @@ private static String quote(String nullableString) {
}
private void setDownloadAndInstallSize(PluginRef pluginRefToEdit, File artifact) {
- if (!pluginRefToEdit.hasInstallSize() && !pluginRefToEdit.hasDownloadSize()) {
- return;
- }
+ // TODO 375111 optionally disable this?
long downloadSize = 0;
long installSize = 0;
if (artifact.isFile()) {
@@ -168,23 +166,26 @@ private void setDownloadAndInstallSize(PluginRef pluginRefToEdit, File artifact)
} else {
log.info("Download/install size is not calculated for directory based bundle " + pluginRefToEdit.getId());
}
- if (pluginRefToEdit.hasDownloadSize()) {
- pluginRefToEdit.setDownloadSize(downloadSize / KBYTE);
- }
- if (pluginRefToEdit.hasInstallSize()) {
- pluginRefToEdit.setInstallSize(installSize / KBYTE);
- }
+
+ pluginRefToEdit.setDownloadSize(downloadSize / KBYTE);
+ pluginRefToEdit.setInstallSize(installSize / KBYTE);
}
protected long getInstallSize(File location) {
- FileLocker locker = fileLockService.getFileLocker(location);
- locker.lock();
- try (JarFile jar = new JarFile(location)) {
- return jar.stream().mapToLong(JarEntry::getSize).filter(s -> s > 0).sum();
+ long installSize = 0;
+ try (var locked = fileLockService.lock(location); //
+ JarFile jar = new JarFile(location);) {
+ Enumeration entries = jar.entries();
+ while (entries.hasMoreElements()) {
+ JarEntry entry = entries.nextElement();
+ long entrySize = entry.getSize();
+ if (entrySize > 0) {
+ installSize += entrySize;
+ }
+ }
} catch (IOException e) {
throw new RuntimeException("Could not determine installation size of file " + location, e);
- } finally {
- locker.release();
}
+ return installSize;
}
}
diff --git a/tycho-packaging-plugin/src/main/java/org/eclipse/tycho/packaging/UpdateSiteAssembler.java b/tycho-packaging-plugin/src/main/java/org/eclipse/tycho/packaging/UpdateSiteAssembler.java
index a275afbeaf..bd22800ab7 100644
--- a/tycho-packaging-plugin/src/main/java/org/eclipse/tycho/packaging/UpdateSiteAssembler.java
+++ b/tycho-packaging-plugin/src/main/java/org/eclipse/tycho/packaging/UpdateSiteAssembler.java
@@ -28,7 +28,6 @@
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.util.FileUtils;
import org.eclipse.tycho.FileLockService;
-import org.eclipse.tycho.FileLocker;
import org.eclipse.tycho.ReactorProject;
import org.eclipse.tycho.core.ArtifactDependencyVisitor;
import org.eclipse.tycho.core.FeatureDescription;
@@ -199,15 +198,11 @@ private void unpackJar(File location, File outputJar) {
unzip.setSourceFile(location);
unzip.setDestDirectory(outputJar);
- FileLocker locker = fileLockService.getFileLocker(location);
- locker.lock();
- try {
+ try (var locked = fileLockService.lock(location)) {
unzip.extract();
- } catch (ArchiverException e) {
+ } catch (ArchiverException | IOException e) {
throw new RuntimeException("Could not unpack jar", e);
- } finally {
- locker.release();
- }
+ }
}
private void copyDir(File location, File outputJar) {
diff --git a/tycho-testing-harness/src/main/java/org/eclipse/tycho/test/util/NoopFileLockService.java b/tycho-testing-harness/src/main/java/org/eclipse/tycho/test/util/NoopFileLockService.java
index 51751e8ade..566e9d38b0 100644
--- a/tycho-testing-harness/src/main/java/org/eclipse/tycho/test/util/NoopFileLockService.java
+++ b/tycho-testing-harness/src/main/java/org/eclipse/tycho/test/util/NoopFileLockService.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011, 2012 SAP SE and others.
+ * Copyright (c) 2011, 2023 SAP SE and others.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
@@ -13,29 +13,21 @@
package org.eclipse.tycho.test.util;
+import java.io.Closeable;
import java.io.File;
import org.eclipse.tycho.FileLockService;
-import org.eclipse.tycho.FileLocker;
-import org.eclipse.tycho.LockTimeoutException;
public class NoopFileLockService implements FileLockService {
@Override
- public FileLocker getFileLocker(File file) {
- return new FileLocker() {
-
- @Override
- public void release() {
- }
-
- @Override
- public void lock() {
- }
+ public Closeable lock(File file, long timeout) {
+ return lockVirtually(file);
+ }
- @Override
- public void lock(long timeout) throws LockTimeoutException {
- }
+ @Override
+ public Closeable lockVirtually(File file) {
+ return () -> {
};
}