diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index d925790a8e..973c7f4cfa 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -23,9 +23,9 @@ jobs: matrix: os: [ubuntu-latest, windows-latest, macos-latest] steps: - - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: Set up Java - uses: actions/setup-java@5ffc13f4174014e2d4d4572b3d74c3fa61aeb2c2 # v3.11.0 + uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 # v4.0.0 with: java-version: | 8 @@ -34,7 +34,7 @@ jobs: 17 distribution: 'temurin' - name: Cache local Maven repository - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 + uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2 with: path: ~/.m2/repository key: ${{ runner.os }}-tycho4m39-${{ matrix.os }}-${{ hashFiles('**/pom.xml', '**/*.target') }} @@ -51,7 +51,7 @@ jobs: cp .github/toolchains.xml ~/.m2/toolchains.xml mvn -U -V -e -B -ntp clean install --file pom.xml -DtrimStackTrace=false -Pits -fae - name: Upload Test Results - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 if: always() with: name: test-results-${{ matrix.os }} @@ -63,7 +63,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Upload - uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 + uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 with: name: Event File path: ${{ github.event_path }} diff --git a/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/transport/URLHttpTransportFactory.java b/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/transport/URLHttpTransportFactory.java index 163a314f28..3b98137aac 100644 --- a/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/transport/URLHttpTransportFactory.java +++ b/p2-maven-plugin/src/main/java/org/eclipse/tycho/p2maven/transport/URLHttpTransportFactory.java @@ -63,7 +63,7 @@ public void setHeader(String key, String value) { public Response get() throws IOException { HttpURLConnection connection = createConnection(); connection.connect(); - return new HttpResponse(connection) { + return new HttpResponse<>(connection) { @Override public void close() { @@ -111,7 +111,7 @@ public Response head() throws IOException { HttpURLConnection connection = createConnection(); connection.setRequestMethod("HEAD"); connection.connect(); - return new HttpResponse(connection) { + return new HttpResponse<>(connection) { @Override public void close() { diff --git a/sisu-osgi/sisu-osgi-connect/pom.xml b/sisu-osgi/sisu-osgi-connect/pom.xml index baec763bd8..326ae2c718 100644 --- a/sisu-osgi/sisu-osgi-connect/pom.xml +++ b/sisu-osgi/sisu-osgi-connect/pom.xml @@ -35,6 +35,11 @@ commons-io commons-io + + org.eclipse.platform + org.eclipse.equinox.registry + 3.11.400 + diff --git a/sisu-osgi/sisu-osgi-connect/src/main/java/org/eclipse/sisu/osgi/connect/PlexusFrameworkConnectServiceFactory.java b/sisu-osgi/sisu-osgi-connect/src/main/java/org/eclipse/sisu/osgi/connect/PlexusFrameworkConnectServiceFactory.java index c0054fefc6..18d4e70f2d 100644 --- a/sisu-osgi/sisu-osgi-connect/src/main/java/org/eclipse/sisu/osgi/connect/PlexusFrameworkConnectServiceFactory.java +++ b/sisu-osgi/sisu-osgi-connect/src/main/java/org/eclipse/sisu/osgi/connect/PlexusFrameworkConnectServiceFactory.java @@ -45,6 +45,10 @@ import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable; import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException; import org.codehaus.plexus.util.StringUtils; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.IExtensionRegistry; import org.eclipse.sisu.equinox.EquinoxServiceFactory; import org.eclipse.sisu.equinox.embedder.EquinoxLifecycleListener; import org.osgi.framework.Bundle; @@ -152,8 +156,8 @@ synchronized PlexusConnectFramework getFramework(ClassRealm realm) throws Bundle for (EquinoxLifecycleListener listener : lifecycleListeners.values()) { connectFramework.debug("Calling " + listener); try { - listener.afterFrameworkStarted(connectFramework); - } catch(RuntimeException e) { + listener.afterFrameworkStarted(connectFramework); + } catch (RuntimeException e) { log.warn("Internal error in EquinoxLifecycleListener " + listener, e); } } @@ -238,6 +242,62 @@ private static Map readProperties(ClassLoader classloader, Logge private static void printFrameworkState(Framework framework, Logger log) { Bundle[] bundles = printBundles(framework, log); + printComponents(framework, log); + printExtensions(framework, log); + printServices(log, bundles); + } + + private static void printExtensions(Framework framework, Logger log) { + log.info("============ Extension Registry =================="); + ServiceTracker st = new ServiceTracker<>(framework.getBundleContext(), + IExtensionRegistry.class, null); + st.open(true); + try { + IExtensionRegistry registry = st.getService(); + if (registry == null) { + log.info("No IExtensionRegistry installed (or started) in this framework"); + return; + } + IExtensionPoint[] extensionPoints = registry.getExtensionPoints(); + for (IExtensionPoint point : extensionPoints) { + log.info(point.getUniqueIdentifier() + " [contributed by " + point.getContributor() + "]"); + for (IExtension extention : point.getExtensions()) { + log.info("\t" + extention.getUniqueIdentifier() + " [from " + extention.getContributor().getName() + + "]"); + for (IConfigurationElement element : extention.getConfigurationElements()) { + printConfigElement(element, 2, log); + } + } + } + } finally { + st.close(); + } + } + + + + private static void printConfigElement(IConfigurationElement element, int level, Logger log) { + StringBuilder sb = new StringBuilder(); + sb.append("\t".repeat(level)); + sb.append(element.getName()); + for (String attr : element.getAttributeNames()) { + sb.append(' '); + sb.append(attr); + sb.append('='); + sb.append(element.getAttribute(attr)); + } + String value = element.getValue(); + if (value != null) { + sb.append(" @value = "); + sb.append(value); + } + log.info(sb.toString()); + for (IConfigurationElement child : element.getChildren()) { + printConfigElement(child, level + 1, log); + } + } + + private static void printComponents(Framework framework, Logger log) { ServiceTracker st = new ServiceTracker<>( framework.getBundleContext(), ServiceComponentRuntime.class, null); st.open(); @@ -268,6 +328,9 @@ private static void printFrameworkState(Framework framework, Logger log) { } finally { st.close(); } + } + + private static void printServices(Logger log, Bundle[] bundles) { log.info("============ Registered Services =================="); Arrays.stream(bundles).map(Bundle::getRegisteredServices).filter(Objects::nonNull).flatMap(Arrays::stream) .forEach(reference -> { 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-bnd-plugin/src/main/java/org/eclipse/tycho/bnd/maven/BndMavenLifecycleParticipant.java b/tycho-bnd-plugin/src/main/java/org/eclipse/tycho/bnd/maven/BndMavenLifecycleParticipant.java index 73a959c907..7bb401fe07 100644 --- a/tycho-bnd-plugin/src/main/java/org/eclipse/tycho/bnd/maven/BndMavenLifecycleParticipant.java +++ b/tycho-bnd-plugin/src/main/java/org/eclipse/tycho/bnd/maven/BndMavenLifecycleParticipant.java @@ -71,7 +71,7 @@ public void afterProjectsRead(MavenSession session) throws MavenExecutionExcepti Map bndProjects = getProjects(session); Map manifestFirstProjects = getManifestFirstProjects(session, bndProjects.keySet()); Map bndWorkspaceProjects = bndProjects.entrySet().stream() - .collect(Collectors.toMap(e -> e.getValue().getName(), e -> e.getKey(), (a, b) -> { + .collect(Collectors.toMap(e -> e.getValue().getName(), Entry::getKey, (a, b) -> { logger.warn( "Your reactor build contains duplicate BND projects from different workspace, build order might be insufficient!"); logger.warn("\tProject 1 (selected): " + a.getBasedir()); @@ -166,8 +166,8 @@ private Map getManifestFirstProjects(MavenSession session, } private Map getProjects(MavenSession session) { - Set workspaces = new HashSet(); - HashMap result = new HashMap(); + Set workspaces = new HashSet<>(); + HashMap result = new HashMap<>(); for (MavenProject mavenProject : session.getProjects()) { if (isBNDProject(mavenProject)) { try { @@ -203,13 +203,6 @@ static boolean isBNDProject(MavenProject mavenProject) { } } - private void setProperty(Project project, String key, String value) { - String property = project.getProperty(key); - if (property == null || property.isBlank()) { - project.setProperty(key, value); - } - } - private void logError(String msg, Exception e) { if (logger.isDebugEnabled()) { logger.error(msg, e); diff --git a/tycho-compiler-plugin/src/main/java/org/eclipse/tycho/compiler/AbstractOsgiCompilerMojo.java b/tycho-compiler-plugin/src/main/java/org/eclipse/tycho/compiler/AbstractOsgiCompilerMojo.java index 3a8c594234..05598dd3c8 100644 --- a/tycho-compiler-plugin/src/main/java/org/eclipse/tycho/compiler/AbstractOsgiCompilerMojo.java +++ b/tycho-compiler-plugin/src/main/java/org/eclipse/tycho/compiler/AbstractOsgiCompilerMojo.java @@ -330,7 +330,6 @@ public abstract class AbstractOsgiCompilerMojo extends AbstractCompilerMojo impl * And a configuration: * * <configuration> - * <logEnabled>true</logEnabled> * <logDirectory>${project.build.directory}/logfiles</logDirectory> * <log>xml</log> * </configuration> @@ -883,12 +882,12 @@ private ExecutionEnvironment getTargetExecutionEnvironment() { @Override public List getClasspath() throws MojoExecutionException { - ReactorProject reactorProject = DefaultReactorProject.adapt(project); List classpath; String dependencyScope = getDependencyScope(); if (Artifact.SCOPE_TEST.equals(dependencyScope)) { classpath = new ArrayList<>(getBundleProject().getTestClasspath(DefaultReactorProject.adapt(project))); } else { + ReactorProject reactorProject = DefaultReactorProject.adapt(project); classpath = new ArrayList<>(getBundleProject().getClasspath(reactorProject)); } if (extraClasspathElements != null) { @@ -940,7 +939,7 @@ public List getClasspath() throws MojoExecutionException { } } } - List uniqueClasspath = classpathMap.entrySet().stream().flatMap(entry -> { + return classpathMap.entrySet().stream().flatMap(entry -> { List list = entry.getValue(); if (list.isEmpty()) { return Stream.empty(); @@ -949,7 +948,7 @@ public List getClasspath() throws MojoExecutionException { return list.stream(); } ArtifactKey key = entry.getKey(); - ReactorProject compositeProject = findProjectForKey(reactorProject, key); + ReactorProject compositeProject = findProjectForKey(key); List compositeFiles = list.stream().flatMap(cpe -> cpe.getLocations().stream()).toList(); Collection compositeRules = mergeRules(list); return Stream.of(new ClasspathEntry() { @@ -984,7 +983,6 @@ public String toString() { }); }).toList(); - return uniqueClasspath; } private ArtifactKey normalizedKey(ArtifactKey key) { @@ -1014,7 +1012,7 @@ private Collection mergeRules(List list) { return joinedRules; } - private ReactorProject findProjectForKey(ReactorProject root, ArtifactKey key) { + private ReactorProject findProjectForKey(ArtifactKey key) { for (MavenProject p : session.getProjects()) { ReactorProject rp = DefaultReactorProject.adapt(p); try { diff --git a/tycho-core/src/main/java/org/eclipse/tycho/core/bnd/PdeInstallableUnitProvider.java b/tycho-core/src/main/java/org/eclipse/tycho/core/bnd/PdeInstallableUnitProvider.java index 12557f61f4..842bdb815c 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/core/bnd/PdeInstallableUnitProvider.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/core/bnd/PdeInstallableUnitProvider.java @@ -97,8 +97,7 @@ public Collection getInstallableUnits(MavenProject project, Ma Version version = new MavenVersion(project.getVersion()).getOSGiVersion(); pr.setProperty(Constants.BUNDLE_VERSION, version.toString()); } - Collection dependencies = collectInitial(project, new HashMap()) - .values(); + Collection dependencies = collectInitial(project, new HashMap<>()).values(); return generateWithProcessor(project, pr, mavenDependenciesResolver.resolve(project, dependencies, Set.of(Artifact.SCOPE_COMPILE, Artifact.SCOPE_TEST), session)); } catch (Exception e) { 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/maven/JavaHomeToolchain.java b/tycho-core/src/main/java/org/eclipse/tycho/core/maven/JavaHomeToolchain.java index d7c1ecc53a..524859a84b 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/core/maven/JavaHomeToolchain.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/core/maven/JavaHomeToolchain.java @@ -12,8 +12,9 @@ *******************************************************************************/ package org.eclipse.tycho.core.maven; -import java.io.File; -import java.io.FileFilter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; import org.apache.commons.io.FilenameUtils; import org.apache.maven.toolchain.java.JavaToolchain; @@ -21,10 +22,10 @@ final class JavaHomeToolchain implements JavaToolchain { - private String javaHome; + private Path javaHome; public JavaHomeToolchain(String javaHome) { - this.javaHome = javaHome; + this.javaHome = Path.of(javaHome).toAbsolutePath(); } @Override @@ -34,35 +35,25 @@ public String getType() { @Override public String findTool(String toolName) { - File bin = new File(javaHome, "bin"); - if (bin.exists()) { - File tool; - if (TargetEnvironment.getRunningEnvironment().isWindows()) { - tool = new File(bin, toolName + ".exe"); - } else { - tool = new File(bin, toolName); - } - if (tool.exists()) { - return tool.getAbsolutePath(); + Path bin = javaHome.resolve("bin"); + if (Files.isDirectory(bin)) { + Path tool = bin.resolve(toolName + (TargetEnvironment.getRunningEnvironment().isWindows() ? ".exe" : "")); + if (Files.isRegularFile(tool)) { + return tool.toString(); } //last resort just in case other extension or case-sensitive file-system... - File[] listFiles = bin.listFiles(new FileFilter() { - - @Override - public boolean accept(File pathname) { - return pathname.isFile() - && FilenameUtils.getBaseName(pathname.getName().toLowerCase()).equals(toolName); - } - }); - if (listFiles != null && listFiles.length > 0) { - return listFiles[0].getAbsolutePath(); + try (var files = Files.list(bin).filter(Files::isRegularFile)) { + return files.map(Path::toString) + .filter(pathname -> FilenameUtils.getBaseName(pathname).equalsIgnoreCase(toolName)).findFirst() + .orElse(null); + } catch (IOException e) { } } return null; } public String getJavaHome() { - return javaHome; + return javaHome.toString(); } @Override diff --git a/tycho-core/src/main/java/org/eclipse/tycho/core/osgitools/AbstractTychoProject.java b/tycho-core/src/main/java/org/eclipse/tycho/core/osgitools/AbstractTychoProject.java index d45578233c..f0e060e379 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/core/osgitools/AbstractTychoProject.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/core/osgitools/AbstractTychoProject.java @@ -125,7 +125,7 @@ public void setupProject(MavenSession session, MavenProject project) { reactorProject.setContextValue(CTX_MAVEN_SESSION, session); reactorProject.setContextValue(CTX_MAVEN_PROJECT, project); reactorProject.setContextValue(CTX_INITIAL_MAVEN_DEPENDENCIES, - List.copyOf(collectInitial(project, new HashMap()).values())); + List.copyOf(collectInitial(project, new HashMap<>()).values())); } private Map collectInitial(MavenProject project, Map map) { 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/core/osgitools/DependencyComputer.java b/tycho-core/src/main/java/org/eclipse/tycho/core/osgitools/DependencyComputer.java index a198f39808..d37b4529a9 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/core/osgitools/DependencyComputer.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/core/osgitools/DependencyComputer.java @@ -126,7 +126,7 @@ public String toString() { } } - private final class VisiblePackages { + private static final class VisiblePackages { private final Map> visiblePackages = new HashMap<>(); private final BundleRevision consumerHost; diff --git a/tycho-core/src/main/java/org/eclipse/tycho/core/resolver/MavenTargetDefinitionContent.java b/tycho-core/src/main/java/org/eclipse/tycho/core/resolver/MavenTargetDefinitionContent.java index a3a6f55522..3427c5f389 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/core/resolver/MavenTargetDefinitionContent.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/core/resolver/MavenTargetDefinitionContent.java @@ -421,19 +421,6 @@ public IMetadataRepository getMetadataRepository() { return metadataRepository; } - private static String getKey(IArtifactFacade artifact) { - if (artifact == null) { - return ""; - } - String key = artifact.getGroupId() + ":" + artifact.getArtifactId(); - String classifier = artifact.getClassifier(); - if (classifier != null) { - key += ":" + classifier; - } - key += ":" + artifact.getVersion(); - return key; - } - private static String getKey(Artifact artifact) { if (artifact == null) { return ""; diff --git a/tycho-core/src/main/java/org/eclipse/tycho/osgi/framework/EclipseWorkspace.java b/tycho-core/src/main/java/org/eclipse/tycho/osgi/framework/EclipseWorkspace.java index 6759e3ea63..fcc4669eed 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/osgi/framework/EclipseWorkspace.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/osgi/framework/EclipseWorkspace.java @@ -28,8 +28,6 @@ public final class EclipseWorkspace { private T key; - private boolean init; - private Logger logger; private Thread thread; diff --git a/tycho-core/src/main/java/org/eclipse/tycho/osgi/resource/InstallableUnitCapability.java b/tycho-core/src/main/java/org/eclipse/tycho/osgi/resource/InstallableUnitCapability.java index 236c88c3c4..cccd1e42b6 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/osgi/resource/InstallableUnitCapability.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/osgi/resource/InstallableUnitCapability.java @@ -33,7 +33,6 @@ */ public class InstallableUnitCapability implements Capability { - private static final String P2_NS_IDENTITY = "osgi.identity"; private IProvidedCapability capability; private InstallableUnitResource resource; private Map attributes; diff --git a/tycho-core/src/main/java/org/eclipse/tycho/p2/publisher/AuthoredIUAction.java b/tycho-core/src/main/java/org/eclipse/tycho/p2/publisher/AuthoredIUAction.java index 3286aee626..628566b07c 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/p2/publisher/AuthoredIUAction.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/p2/publisher/AuthoredIUAction.java @@ -29,7 +29,6 @@ import org.eclipse.equinox.p2.metadata.MetadataFactory; import org.eclipse.equinox.p2.metadata.MetadataFactory.InstallableUnitDescription; import org.eclipse.equinox.p2.publisher.AbstractPublisherAction; -import org.eclipse.equinox.p2.publisher.IPublisherAction; import org.eclipse.equinox.p2.publisher.IPublisherInfo; import org.eclipse.equinox.p2.publisher.IPublisherResult; import org.eclipse.equinox.p2.repository.artifact.IArtifactDescriptor; @@ -39,7 +38,7 @@ import org.eclipse.tycho.TychoConstants; import org.eclipse.tycho.p2.repository.MetadataIO; -public class AuthoredIUAction extends AbstractPublisherAction implements IPublisherAction { +public class AuthoredIUAction extends AbstractPublisherAction { public static final String IU_TYPE = "org.eclipse.equinox.p2.type.iu"; public File iuProject; diff --git a/tycho-core/src/main/java/org/eclipse/tycho/p2/repository/AbstractArtifactRepository2.java b/tycho-core/src/main/java/org/eclipse/tycho/p2/repository/AbstractArtifactRepository2.java index fe31bbd849..9cc0e9a426 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/p2/repository/AbstractArtifactRepository2.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/p2/repository/AbstractArtifactRepository2.java @@ -233,7 +233,7 @@ public final OutputStream getOutputStream(IArtifactDescriptor descriptor) throws } } - private class CommittingArtifactOutputStream extends OutputStream implements IStateful { + private static class CommittingArtifactOutputStream extends OutputStream implements IStateful { final IArtifactSink artifactSink; final OutputStream artifactOutputStream; 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/main/java/org/eclipse/tycho/p2/repository/MirroringArtifactProvider.java b/tycho-core/src/main/java/org/eclipse/tycho/p2/repository/MirroringArtifactProvider.java index 6a11010030..052ed69f95 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/p2/repository/MirroringArtifactProvider.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/p2/repository/MirroringArtifactProvider.java @@ -88,13 +88,14 @@ public class MirroringArtifactProvider implements IRawArtifactFileProvider { * Creates a new {@link MirroringArtifactProvider} instance. * * @param localArtifactRepository - * The local Maven repository + * The local Maven repository * @param remoteProviders - * The provider that will be queried by this instance when it is asked for an - * artifact which is not (yet) available in the local Maven repository. Typically - * this provider is backed by remote p2 repositories. + * The provider that will be queried by this instance when it is + * asked for an artifact which is not (yet) available in the + * local Maven repository. Typically this provider is backed by + * remote p2 repositories. * @param logger - * a logger for progress output + * a logger for progress output */ public static MirroringArtifactProvider createInstance(LocalArtifactRepository localArtifactRepository, IRawArtifactProvider remoteProviders, MavenContext context) { @@ -198,7 +199,7 @@ public final boolean contains(IArtifactDescriptor descriptor) throws MirroringFa * @return false if the artifact is neither already cached locally nor available * remotely. * @throws MirroringFailedException - * if a fatal error occurred while downloading the artifact. + * if a fatal error occurred while downloading the artifact. */ private boolean makeLocallyAvailable(IArtifactKey key) throws MirroringFailedException { // TODO 397355 cache artifactDescriptors for the key so that only one synchronization is necessary to figure out if a download is needed @@ -207,10 +208,9 @@ private boolean makeLocallyAvailable(IArtifactKey key) throws MirroringFailedExc if (isAvailable) { /* - * Always execute this step so that a local repository that only contains the packed - * format of an artifact is automatically corrected. We need the canonical format in - * the local repository so that {@link - * IArtifactFileProvider#getArtifactFile(IArtifactKey)} does not return null. + * Always execute this step so that a local repository that only contains the packed format of an + * artifact is automatically corrected. We need the canonical format in the local repository so that + * {@link IArtifactFileProvider#getArtifactFile(IArtifactKey)} does not return null. */ ensureArtifactIsPresentInCanonicalFormat(key); } @@ -370,8 +370,8 @@ private static IStatus artifactNotFoundStatus(IArtifactKey key) { } /** - * Returns an {@link IProgressMonitor} which translates p2's status updates into a reasonable - * log output. + * Returns an {@link IProgressMonitor} which translates p2's status updates into a reasonable log + * output. */ final IProgressMonitor monitorForDownload() { // create a new instance for each call - DuplicateFilteringLoggingProgressMonitor is not thread-safe @@ -394,7 +394,7 @@ public static class MirroringFailedException extends RuntimeException { } - private static final class MirrorArtifactDescriptor extends ArtifactDescriptor implements IArtifactDescriptor { + private static final class MirrorArtifactDescriptor extends ArtifactDescriptor { final MirroringArtifactProvider provider; private IArtifactDescriptor base; diff --git a/tycho-core/src/main/java/org/eclipse/tycho/p2/resolver/FileTargetDefinitionContent.java b/tycho-core/src/main/java/org/eclipse/tycho/p2/resolver/FileTargetDefinitionContent.java index 541c4c90e9..eecedab9b4 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/p2/resolver/FileTargetDefinitionContent.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/p2/resolver/FileTargetDefinitionContent.java @@ -43,7 +43,7 @@ public class FileTargetDefinitionContent implements TargetDefinitionContent { - private Map repositoryContent = new HashMap(); + private Map repositoryContent = new HashMap<>(); private final SupplierMetadataRepository metadataRepository; private final FileArtifactRepository artifactRepository; private File location; diff --git a/tycho-core/src/main/java/org/eclipse/tycho/p2/tools/RepositoryReference.java b/tycho-core/src/main/java/org/eclipse/tycho/p2/tools/RepositoryReference.java index c8de3b661d..34d31669fa 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/p2/tools/RepositoryReference.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/p2/tools/RepositoryReference.java @@ -12,28 +12,13 @@ *******************************************************************************/ package org.eclipse.tycho.p2.tools; -public class RepositoryReference { - private final String name; - private final String location; - private final boolean enable; +import java.net.URI; - public RepositoryReference(String name, String location, boolean enable) { - super(); - this.name = name; - this.location = location; - this.enable = enable; - } - - public String getName() { - return name; - } +public record RepositoryReference(String name, String location, boolean enable) { - public String getLocation() { - return location; + public URI locationURINormalized() { + // P2 does the same before loading the repo and thus IRepository.getLocation() returns the normalized URL. + // In order to avoid stripping of slashes from URI instances do it now before URIs are created. + return URI.create(location.endsWith("/") ? location.substring(0, location.length() - 1) : location); } - - public boolean isEnable() { - return enable; - } - } diff --git a/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/P2GeneratorImpl.java b/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/P2GeneratorImpl.java index ba2ff47e21..e79b7abbc8 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/P2GeneratorImpl.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/p2resolver/P2GeneratorImpl.java @@ -202,7 +202,7 @@ public String getArtifactId() { result.put(classifier, p2artifact); }, () -> { logger.debug("Skip generation of secondary metadata for artifact = " + artifact - + ", as it does not has a canonical ArtifactDescriptor"); + + ", as it does not have a canonical ArtifactDescriptor"); }); } @@ -365,7 +365,7 @@ public boolean isSupported(String type) { /** * Looks for all files at the base of the project that extension is ".product" Duplicated in the * EclipseRepositoryProject - * + * * @param projectLocation * @return The list of product files to parse for an eclipse-repository project */ diff --git a/tycho-core/src/main/java/org/eclipse/tycho/p2tools/MirrorApplicationServiceImpl.java b/tycho-core/src/main/java/org/eclipse/tycho/p2tools/MirrorApplicationServiceImpl.java index aeb833ffbb..a715ef23a1 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/p2tools/MirrorApplicationServiceImpl.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/p2tools/MirrorApplicationServiceImpl.java @@ -162,7 +162,6 @@ public void mirrorReactor(RepositoryReferences sources, DestinationRepositoryDes mirrorApp.setIncludeSources(includeAllSource, sources.getTargetPlatform()); mirrorApp.setIncludeRequiredBundles(includeRequiredBundles); mirrorApp.setIncludeRequiredFeatures(includeRequiredFeatures); - mirrorApp.setIncludePacked(false); // no way, Tycho do no longer support packed artifacts anyways mirrorApp.setFilterProvided(filterProvided); mirrorApp.setAddOnlyProvidingRepoReferences(addOnlyProvidingRepoReferences); mirrorApp.setEnvironments(context.getEnvironments()); @@ -360,7 +359,7 @@ public void close() { } - private final class MappingRule { + private static final class MappingRule { public final String filter; public final String urlPattern; diff --git a/tycho-core/src/main/java/org/eclipse/tycho/p2tools/TychoMirrorApplication.java b/tycho-core/src/main/java/org/eclipse/tycho/p2tools/TychoMirrorApplication.java index 7e51c61b86..b9fc834736 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/p2tools/TychoMirrorApplication.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/p2tools/TychoMirrorApplication.java @@ -198,15 +198,15 @@ private static Stream RepositoryReference rr) { return Stream.of(IRepository.TYPE_METADATA, IRepository.TYPE_ARTIFACT).map(type -> { URI location = getNormalizedLocation(rr); - int options = rr.isEnable() ? IRepository.ENABLED : IRepository.NONE; - return new org.eclipse.equinox.p2.repository.spi.RepositoryReference(location, rr.getName(), type, options); + int options = rr.enable() ? IRepository.ENABLED : IRepository.NONE; + return new org.eclipse.equinox.p2.repository.spi.RepositoryReference(location, rr.name(), type, options); }); } private static URI getNormalizedLocation(RepositoryReference r) { // P2 does the same before loading the repo and thus IRepository.getLocation() returns the normalized URL. // In order to avoid stripping of slashes from URI instances do it now before URIs are created. - String location = r.getLocation(); + String location = r.location(); return URI.create(location.endsWith("/") ? location.substring(0, location.length() - 1) : location); } diff --git a/tycho-core/src/main/java/org/eclipse/tycho/p2tools/copiedfromp2/MirrorApplication.java b/tycho-core/src/main/java/org/eclipse/tycho/p2tools/copiedfromp2/MirrorApplication.java index 3f939e95ca..8b866fbbf5 100644 --- a/tycho-core/src/main/java/org/eclipse/tycho/p2tools/copiedfromp2/MirrorApplication.java +++ b/tycho-core/src/main/java/org/eclipse/tycho/p2tools/copiedfromp2/MirrorApplication.java @@ -73,7 +73,6 @@ public class MirrorApplication extends AbstractApplication implements IApplicati private boolean mirrorReferences = true; private String metadataOrArtifacts = null; private String[] rootIUs = null; - private boolean includePacked = true; private boolean mirrorProperties = false; private File mirrorLogFile; // file to log mirror output to (optional) @@ -281,7 +280,7 @@ protected Mirroring getMirroring(Collection ius, IProgressMoni * Collect all artifacts from the IUs that should be mirrored * * @param ius - * the IUs that are selected for mirroring + * the IUs that are selected for mirroring * @return a (modifiable) list of {@link IArtifactKey}s that must be mirrored */ protected List collectArtifactKeys(Collection ius, IProgressMonitor monitor) @@ -316,7 +315,7 @@ private void mirrorMetadata(Collection units, IProgressMonitor * Collect all IUS from the slice that should be mirrored * * @param slice - * the slice for mirroring + * the slice for mirroring * @return a (modifiable) set of {@link IInstallableUnit}s that must be mirrored * @throws ProvisionException */ @@ -328,9 +327,9 @@ protected Set collectUnits(IQueryable slice, } /* - * Ensure all mandatory parameters have been set. Throw an exception if there are any missing. - * We don't require the user to specify the artifact repository here, we will default to the - * ones already registered in the manager. (callers are free to add more if they wish) + * Ensure all mandatory parameters have been set. Throw an exception if there are any missing. We + * don't require the user to specify the artifact repository here, we will default to the ones + * already registered in the manager. (callers are free to add more if they wish) */ private void validate() throws ProvisionException { if (sourceRepositories.isEmpty()) @@ -557,10 +556,6 @@ public void setComparatorExclusions(IQuery exclusions) { compareExclusions = exclusions; } - public void setIncludePacked(boolean includePacked) { - this.includePacked = includePacked; - } - public void setMirrorProperties(boolean mirrorProperties) { this.mirrorProperties = mirrorProperties; } 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-core/src/test/java/org/eclipse/tycho/p2resolver/DependencyCollectorTest.java b/tycho-core/src/test/java/org/eclipse/tycho/p2resolver/DependencyCollectorTest.java index 9b8f09a7ef..034eb9c87c 100644 --- a/tycho-core/src/test/java/org/eclipse/tycho/p2resolver/DependencyCollectorTest.java +++ b/tycho-core/src/test/java/org/eclipse/tycho/p2resolver/DependencyCollectorTest.java @@ -59,8 +59,8 @@ public void missingDependencies() { ResolutionDataImpl data = new ResolutionDataImpl(ExecutionEnvironmentTestUtils.NOOP_EE_RESOLUTION_HINTS); data.setRootIUs(rootUIs); - data.setAdditionalRequirements(new ArrayList()); - data.setAvailableIUs(Collections. emptyList()); + data.setAdditionalRequirements(new ArrayList<>()); + data.setAvailableIUs(Collections.emptyList()); DependencyCollector dc = new DependencyCollector(new MavenLoggerAdapter(logVerifier.getLogger(), false)); dc.setData(data); diff --git a/tycho-core/src/test/java/org/eclipse/tycho/p2resolver/RemoteAgentMavenMirrorsTest.java b/tycho-core/src/test/java/org/eclipse/tycho/p2resolver/RemoteAgentMavenMirrorsTest.java index 7e6727c79e..faf1da7d14 100644 --- a/tycho-core/src/test/java/org/eclipse/tycho/p2resolver/RemoteAgentMavenMirrorsTest.java +++ b/tycho-core/src/test/java/org/eclipse/tycho/p2resolver/RemoteAgentMavenMirrorsTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012 SAP AG and others. + * Copyright (c) 2012, 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 @@ -27,7 +27,6 @@ import org.eclipse.tycho.IRepositoryIdManager; import org.eclipse.tycho.core.test.utils.ResourceUtil; import org.eclipse.tycho.p2maven.repository.DefaultMavenRepositorySettings; -import org.eclipse.tycho.p2maven.transport.DefaultTransportCacheConfig; import org.eclipse.tycho.test.util.HttpServer; import org.eclipse.tycho.test.util.LogVerifier; import org.eclipse.tycho.testing.TychoPlexusTestCase; @@ -46,7 +45,6 @@ public class RemoteAgentMavenMirrorsTest extends TychoPlexusTestCase { public HttpServer localServer = new HttpServer(); private IProvisioningAgent subject; - private DefaultTransportCacheConfig transportConfig; @Before public void initSubject() throws Exception { diff --git a/tycho-core/src/test/java/org/eclipse/tycho/test/util/ArtifactRepositoryTestUtils.java b/tycho-core/src/test/java/org/eclipse/tycho/test/util/ArtifactRepositoryTestUtils.java index 6cf4e76b86..65d90db7be 100644 --- a/tycho-core/src/test/java/org/eclipse/tycho/test/util/ArtifactRepositoryTestUtils.java +++ b/tycho-core/src/test/java/org/eclipse/tycho/test/util/ArtifactRepositoryTestUtils.java @@ -41,7 +41,7 @@ public static IArtifactDescriptor canonicalDescriptorFor(IArtifactKey key) { } public static Matcher inCanonicalFormat() { - return new TypeSafeMatcher() { + return new TypeSafeMatcher<>() { @Override public void describeTo(Description description) { diff --git a/tycho-core/src/test/java/org/eclipse/tycho/test/util/InstallableUnitMatchers.java b/tycho-core/src/test/java/org/eclipse/tycho/test/util/InstallableUnitMatchers.java index 2fa0609fbd..9309ec53df 100644 --- a/tycho-core/src/test/java/org/eclipse/tycho/test/util/InstallableUnitMatchers.java +++ b/tycho-core/src/test/java/org/eclipse/tycho/test/util/InstallableUnitMatchers.java @@ -31,7 +31,7 @@ public class InstallableUnitMatchers { private static final String TYPE = "IInstallableUnit"; public static Matcher unitWithId(final String id) { - return new TypeSafeMatcher(IInstallableUnit.class) { + return new TypeSafeMatcher<>(IInstallableUnit.class) { @Override public void describeTo(Description description) { @@ -169,7 +169,7 @@ public void describeTo(Description description) { public static Matcher requirement(final String id, final String version) { final IInstallableUnit unit = InstallableUnitUtil.createIU(id, version); - return new TypeSafeMatcher() { + return new TypeSafeMatcher<>() { @Override public void describeTo(Description description) { @@ -201,7 +201,7 @@ protected boolean matchesSafely(IRequirement item) { public static Matcher configureTouchpointInstructionThat( final Matcher instructionMatcher) { - return new TypeSafeMatcher() { + return new TypeSafeMatcher<>() { @Override public void describeTo(Description description) { diff --git a/tycho-core/src/test/java/org/eclipse/tycho/test/util/LogVerifier.java b/tycho-core/src/test/java/org/eclipse/tycho/test/util/LogVerifier.java index 1f366ddd32..20009be152 100644 --- a/tycho-core/src/test/java/org/eclipse/tycho/test/util/LogVerifier.java +++ b/tycho-core/src/test/java/org/eclipse/tycho/test/util/LogVerifier.java @@ -38,7 +38,7 @@ public class LogVerifier extends Verifier { private static boolean WRITE_TO_CONSOLE = false; - private class MemoryLog implements Logger { + private static class MemoryLog implements Logger { final StringBuilder errors = new StringBuilder(); final StringBuilder warnings = new StringBuilder(); diff --git a/tycho-extras/tycho-document-bundle-plugin/src/test/java/org/eclipse/tycho/extras/docbundle/PackageNameMatcherTest.java b/tycho-extras/tycho-document-bundle-plugin/src/test/java/org/eclipse/tycho/extras/docbundle/PackageNameMatcherTest.java index 747af41822..d81e6134e3 100644 --- a/tycho-extras/tycho-document-bundle-plugin/src/test/java/org/eclipse/tycho/extras/docbundle/PackageNameMatcherTest.java +++ b/tycho-extras/tycho-document-bundle-plugin/src/test/java/org/eclipse/tycho/extras/docbundle/PackageNameMatcherTest.java @@ -27,7 +27,7 @@ class PackageNameMatcherTest { @Test void testNoPattern() { - assertNotNull(PackageNameMatcher.compile(new ArrayList())); + assertNotNull(PackageNameMatcher.compile(new ArrayList<>())); } @Test diff --git a/tycho-extras/tycho-p2-extras-plugin/src/main/java/org/eclipse/tycho/plugins/p2/extras/CompareWithBaselineMojo.java b/tycho-extras/tycho-p2-extras-plugin/src/main/java/org/eclipse/tycho/plugins/p2/extras/CompareWithBaselineMojo.java index 846c59f649..45682644c2 100644 --- a/tycho-extras/tycho-p2-extras-plugin/src/main/java/org/eclipse/tycho/plugins/p2/extras/CompareWithBaselineMojo.java +++ b/tycho-extras/tycho-p2-extras-plugin/src/main/java/org/eclipse/tycho/plugins/p2/extras/CompareWithBaselineMojo.java @@ -30,8 +30,8 @@ import org.apache.maven.project.MavenProject; import org.codehaus.plexus.logging.Logger; import org.eclipse.equinox.p2.metadata.IInstallableUnit; -import org.eclipse.tycho.IDependencyMetadata.DependencyMetadataType; import org.eclipse.tycho.ExecutionEnvironmentConfiguration; +import org.eclipse.tycho.IDependencyMetadata.DependencyMetadataType; import org.eclipse.tycho.ReactorProject; import org.eclipse.tycho.TargetEnvironment; import org.eclipse.tycho.TargetPlatform; @@ -52,16 +52,16 @@ * This mojo compares versions the output artifacts of your module build with the version of the * same artifacts available in configured baselines, in order to detect version inconsistencies * (version moved back, or not correctly bumped since last release). - * + * * Rules for "illegal" versions are: *
  • version decreased compared to baseline
  • *
  • same fully-qualified version as baseline, but with different binary content
  • *
  • same major.minor.micro as baseline, with different qualifier (at least micro should be * increased)
  • - * + * * This mojo doesn't allow to use qualifier as a versioning segment and will most likely drive to * false-positive errors if your qualifier has means to show versioniterations. - * + * * @author mistria */ @Mojo(defaultPhase = LifecyclePhase.VERIFY, requiresProject = false, name = "compare-version-with-baselines", threadSafe = true) @@ -87,14 +87,14 @@ public static enum ReportBehavior { /** * A list of file path patterns that are ignored when comparing the build artifact against the * baseline version. - * + * * {@code * * META-INF/ECLIPSE_.RSA * META-INF/ECLIPSE_.SF * * } - * + * */ @Parameter private List ignoredPatterns; @@ -169,7 +169,7 @@ public void execute() throws MojoExecutionException, MojoFailureException { getLog().debug("Found " + foundInBaseline.getId() + "/" + foundInBaseline.getVersion() + " with delta: " + versionDelta); if (version.compareTo(baselineVersion) < 0) { - String message = "Version have moved backwards for (" + id + "/" + version + "). Baseline has " + String message = "Version has moved backwards for (" + id + "/" + version + "). Baseline has " + baselineVersion + ") with delta: " + versionDelta; if (this.onIllegalVersion == ReportBehavior.warn) { getLog().warn(message); diff --git a/tycho-its/projects/eeProfile.custom/repository/content.xml b/tycho-its/projects/eeProfile.custom/repository/content.xml index 9fc5212d19..74af616e8b 100644 --- a/tycho-its/projects/eeProfile.custom/repository/content.xml +++ b/tycho-its/projects/eeProfile.custom/repository/content.xml @@ -220,6 +220,7 @@ + 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-its/src/test/java/org/eclipse/tycho/test/target/TargetDefinitionPackagingTypeTest.java b/tycho-its/src/test/java/org/eclipse/tycho/test/target/TargetDefinitionPackagingTypeTest.java index 895d4ddbf1..425be479ed 100644 --- a/tycho-its/src/test/java/org/eclipse/tycho/test/target/TargetDefinitionPackagingTypeTest.java +++ b/tycho-its/src/test/java/org/eclipse/tycho/test/target/TargetDefinitionPackagingTypeTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012, 2018 SAP AG and others. + * Copyright (c) 2012, 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 diff --git a/tycho-metadata-model/src/main/java/org/eclipse/tycho/model/Feature.java b/tycho-metadata-model/src/main/java/org/eclipse/tycho/model/Feature.java index 254386288b..a6c0821a78 100644 --- a/tycho-metadata-model/src/main/java/org/eclipse/tycho/model/Feature.java +++ b/tycho-metadata-model/src/main/java/org/eclipse/tycho/model/Feature.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2020 Sonatype Inc. and others. + * Copyright (c) 2008, 2023 Sonatype Inc. 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 @@ -52,13 +52,13 @@ public class Feature { */ public static final String MATCH_GREATER_OR_EQUAL = "greaterOrEqual"; /** - * dependent plug-in version must be at least at the version specified, or at a higher service - * level or minor level (major version level must equal the specified version). + * dependent plug-in version must be at least at the version specified, or at a higher service level + * or minor level (major version level must equal the specified version). */ public static final String MATCH_COMPATIBLE = "compatible"; /** - * dependent plug-in version must be at least at the version specified, or at a higher service - * level (major and minor version levels must equal the specified version). + * dependent plug-in version must be at least at the version specified, or at a higher service level + * (major and minor version levels must equal the specified version). */ public static final String MATCH_EQUIVALENT = "equivalent"; /** @@ -316,7 +316,7 @@ public static Feature readJar(File file) throws IOException { * Convenience method to load feature.xml file from either feature jar file or directory. * * @throws RuntimeException - * if feature descriptor can not be read or parsed. + * if feature descriptor can not be read or parsed. */ public static Feature loadFeature(File location) { try { @@ -565,16 +565,4 @@ public Resource toJarResource() { } return featureJar.build(); } - - private boolean isVersionedRef(ImportRef importRef) { - String version = importRef.getVersion(); - if (version == null || version.isEmpty()) { - return false; - } - String match = importRef.getMatch(); - if (match == null || match.isEmpty()) { - return false; - } - return true; - } } 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-p2-repository-plugin/src/main/java/org/eclipse/tycho/plugins/p2/repository/ArchiveRepositoryMojo.java b/tycho-p2-repository-plugin/src/main/java/org/eclipse/tycho/plugins/p2/repository/ArchiveRepositoryMojo.java index edf83d6e73..57b577d387 100644 --- a/tycho-p2-repository-plugin/src/main/java/org/eclipse/tycho/plugins/p2/repository/ArchiveRepositoryMojo.java +++ b/tycho-p2-repository-plugin/src/main/java/org/eclipse/tycho/plugins/p2/repository/ArchiveRepositoryMojo.java @@ -25,6 +25,7 @@ import org.codehaus.plexus.archiver.Archiver; import org.codehaus.plexus.archiver.ArchiverException; import org.codehaus.plexus.archiver.util.DefaultFileSet; +import org.eclipse.tycho.FileLockService; /** *

    @@ -33,7 +34,6 @@ */ @Mojo(name = "archive-repository", defaultPhase = LifecyclePhase.PACKAGE, threadSafe = true) public final class ArchiveRepositoryMojo extends AbstractRepositoryMojo { - private static final Object LOCK = new Object(); @Component(role = Archiver.class, hint = "zip") private Archiver inflater; @@ -52,27 +52,25 @@ public final class ArchiveRepositoryMojo extends AbstractRepositoryMojo { @Parameter(defaultValue = "false") private boolean skipArchive; + @Component + private FileLockService fileLockService; + @Override public void execute() throws MojoExecutionException, MojoFailureException { if (skipArchive) { return; } - - synchronized (LOCK) { - File destFile = getBuildDirectory().getChild(finalName + ".zip"); - - try { - inflater.addFileSet(DefaultFileSet.fileSet(getAssemblyRepositoryLocation()).prefixed("")); - inflater.setDestFile(destFile); - inflater.createArchive(); - } catch (ArchiverException e) { - throw new MojoExecutionException("Error packing p2 repository", e); - } catch (IOException e) { - throw new MojoExecutionException("Error packing p2 repository", e); - } - - getProject().getArtifact().setFile(destFile); + File repositoryLocation = getAssemblyRepositoryLocation(); + File destFile = getBuildDirectory().getChild(finalName + ".zip"); + try (var repoLock = fileLockService.lockVirtually(repositoryLocation); + var destLock = fileLockService.lockVirtually(destFile);) { + inflater.addFileSet(DefaultFileSet.fileSet(repositoryLocation).prefixed("")); + inflater.setDestFile(destFile); + inflater.createArchive(); + } catch (ArchiverException | IOException e) { + throw new MojoExecutionException("Error packing p2 repository", e); } + getProject().getArtifact().setFile(destFile); } } diff --git a/tycho-p2-repository-plugin/src/main/java/org/eclipse/tycho/plugins/p2/repository/RemapArtifactToMavenRepositoriesMojo.java b/tycho-p2-repository-plugin/src/main/java/org/eclipse/tycho/plugins/p2/repository/RemapArtifactToMavenRepositoriesMojo.java index 0600d4b007..15d69a1ed9 100644 --- a/tycho-p2-repository-plugin/src/main/java/org/eclipse/tycho/plugins/p2/repository/RemapArtifactToMavenRepositoriesMojo.java +++ b/tycho-p2-repository-plugin/src/main/java/org/eclipse/tycho/plugins/p2/repository/RemapArtifactToMavenRepositoriesMojo.java @@ -9,6 +9,8 @@ *******************************************************************************/ package org.eclipse.tycho.plugins.p2.repository; +import java.io.File; +import java.io.IOException; import java.net.URI; import org.apache.maven.artifact.repository.ArtifactRepository; @@ -17,6 +19,7 @@ import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; +import org.eclipse.tycho.FileLockService; import org.eclipse.tycho.p2.tools.FacadeException; import org.eclipse.tycho.p2.tools.mirroring.facade.MirrorApplicationService; @@ -25,22 +28,25 @@ * artifacts the can be resolved to Maven repositories so the URL under Maven repository is used for * fetching and artifact is not duplicated inside this repo. */ -@Mojo(name = "remap-artifacts-to-m2-repo", defaultPhase = LifecyclePhase.PREPARE_PACKAGE) +@Mojo(name = "remap-artifacts-to-m2-repo", defaultPhase = LifecyclePhase.PREPARE_PACKAGE, threadSafe = true) public class RemapArtifactToMavenRepositoriesMojo extends AbstractRepositoryMojo { - @Component() + @Component MirrorApplicationService mirrorApp; + @Component + private FileLockService fileLockService; @Override public void execute() throws MojoExecutionException, MojoFailureException { - try { - mirrorApp.addMavenMappingRules(getAssemblyRepositoryLocation(), - getProject().getRemoteArtifactRepositories().stream() // + File location = getAssemblyRepositoryLocation(); + try (var locking = fileLockService.lockVirtually(location)) { + mirrorApp.addMavenMappingRules( // + location, getProject().getRemoteArtifactRepositories().stream() // .filter(artifactRepo -> artifactRepo.getLayout().getId().equals("default")) // .map(ArtifactRepository::getUrl) // .map(URI::create) // .toArray(URI[]::new)); - } catch (FacadeException e) { + } catch (IOException | FacadeException e) { throw new MojoExecutionException(e.getMessage(), 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..6bee5ea5d1 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; @@ -177,14 +177,20 @@ private void setDownloadAndInstallSize(PluginRef pluginRefToEdit, File artifact) } 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-source-plugin/src/main/java/org/eclipse/tycho/source/SourceFeatureMojo.java b/tycho-source-plugin/src/main/java/org/eclipse/tycho/source/SourceFeatureMojo.java index cf4e170897..67d3b6c290 100644 --- a/tycho-source-plugin/src/main/java/org/eclipse/tycho/source/SourceFeatureMojo.java +++ b/tycho-source-plugin/src/main/java/org/eclipse/tycho/source/SourceFeatureMojo.java @@ -9,7 +9,7 @@ * * Contributors: * Sonatype Inc. - initial API and implementation - * Bachmann GmbH. - Bug 538395 Generate valid feature xml + * Bachmann GmbH. - Bug 538395 Generate valid feature xml * Christoph Läubrich - Bug 568359 - move tycho-extras SourceFeatureMojo to tycho-source-feature *******************************************************************************/ package org.eclipse.tycho.source; @@ -84,13 +84,13 @@ *

  • Includes the original feature. This ensures that binaries and corresponding sources * match.
  • * - * + * * Source feature generation can be customized by adding files under path * sourceTemplateFeature/. Files added here will be added to the root of the source * feature jar. Especially, if file sourceTemplateFeature/feature.properties is found, * values in this file override values of respective keys in * <originalFeature>/feature.properties. - * + * */ @Mojo(name = SourceFeatureMojo.GOAL, defaultPhase = LifecyclePhase.PACKAGE, threadSafe = true) public class SourceFeatureMojo extends AbstractMojo { @@ -160,14 +160,14 @@ public enum MissingSourcesAction { /** * Bundles and features that do not have corresponding sources. Example: - * + * *
          * <excludes>
          *   <plugin id="plugin.nosource"/>
          *   <feature id="feature.nosource"/>
          * </excludes>
          * 
    - * + * */ @Parameter private PlexusConfiguration excludes; @@ -180,7 +180,7 @@ public enum MissingSourcesAction { *

    * WARNING This experimental parameter may be removed from future * source-feature mojo versions without prior notice. - * + * */ @Parameter private PlexusConfiguration plugins; @@ -382,7 +382,7 @@ Feature createSourceFeatureSkeleton(Feature feature, Properties mergedFeaturePro mergedFeatureProperties.setProperty(labelKey, mergedFeatureProperties.getProperty(labelKey) + labelSuffix); } else { - // keep source template value + // keep source template value } } else { sourceFeature.setLabel(originalLabel + labelSuffix); @@ -432,7 +432,7 @@ Feature createSourceFeatureSkeleton(Feature feature, Properties mergedFeaturePro /** * Returns the value for a field. In case the value is a reference to feature.properties, verify * that the entry exist in the feature.properties file for source - * + * * @param fieldValue * @param sourceFeatureProperties * @return @@ -451,7 +451,7 @@ private static String validateValue(String fieldValue, Properties sourceFeatureP /** * Added all references to sourceFeature, as deduced by feature and resolved by targetPlatform - * + * * @param sourceFeature * @param feature * @param targetPlatform @@ -537,9 +537,9 @@ private void fillReferences(Feature sourceFeature, Feature feature, TargetPlatfo throw new MojoExecutionException(sb.toString()); } else { - reportMissing("The following referenced plugins has missing sources", missingSourcePlugins); - reportMissing("The following referenced features has missing sources", missingSourceFeatures); - reportMissing("The following referenced extra plugins has missing sources", missingExtraPlugins); + reportMissing("The following referenced plugins have missing sources", missingSourcePlugins); + reportMissing("The following referenced features have missing sources", missingSourceFeatures); + reportMissing("The following referenced extra plugins have missing sources", missingExtraPlugins); } } diff --git a/tycho-surefire/tycho-surefire-plugin/src/main/java/org/eclipse/tycho/surefire/AbstractEclipseTestMojo.java b/tycho-surefire/tycho-surefire-plugin/src/main/java/org/eclipse/tycho/surefire/AbstractEclipseTestMojo.java index 45c3f81f72..ca3159fd6d 100644 --- a/tycho-surefire/tycho-surefire-plugin/src/main/java/org/eclipse/tycho/surefire/AbstractEclipseTestMojo.java +++ b/tycho-surefire/tycho-surefire-plugin/src/main/java/org/eclipse/tycho/surefire/AbstractEclipseTestMojo.java @@ -349,12 +349,12 @@ public abstract class AbstractEclipseTestMojo extends AbstractTestMojo { protected DependencyResolver dependencyResolver; /** - * Normally tycho will automatically determine the test framework provider based on the test - * project's classpath. Use this to force using a test framework provider implementation with - * the given role hint. Tycho comes with providers - * "junit3","junit4","junit47","junit5". Note that when - * specifying a providerHint, you have to make sure the provider is actually available in the - * dependencies of tycho-surefire-plugin. + * Normally, Tycho will automatically determine the test framework provider based on the test + * project's classpath. This options forces the use of a test framework provider implementation + * with the given role hint. Tycho comes with providers such as + * "junit3","junit4","junit47","junit5", or + * "junit59". Note that when specifying a providerHint, you have to make sure the + * provider is actually available in the dependencies of tycho-surefire-plugin. * * @since 0.16.0 */ diff --git a/tycho-surefire/tycho-surefire-plugin/src/main/java/org/eclipse/tycho/surefire/TychoVerifyMojo.java b/tycho-surefire/tycho-surefire-plugin/src/main/java/org/eclipse/tycho/surefire/TychoVerifyMojo.java index 119e19e3f6..cf06f5a250 100644 --- a/tycho-surefire/tycho-surefire-plugin/src/main/java/org/eclipse/tycho/surefire/TychoVerifyMojo.java +++ b/tycho-surefire/tycho-surefire-plugin/src/main/java/org/eclipse/tycho/surefire/TychoVerifyMojo.java @@ -12,8 +12,6 @@ ******************************************************************************/ package org.eclipse.tycho.surefire; -import java.io.File; - import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugin.failsafe.VerifyMojo; diff --git a/tycho-targetplatform/src/main/java/org/eclipse/tycho/targetplatform/TargetDefinition.java b/tycho-targetplatform/src/main/java/org/eclipse/tycho/targetplatform/TargetDefinition.java index 4278be692a..ca591b0b7b 100644 --- a/tycho-targetplatform/src/main/java/org/eclipse/tycho/targetplatform/TargetDefinition.java +++ b/tycho-targetplatform/src/main/java/org/eclipse/tycho/targetplatform/TargetDefinition.java @@ -18,7 +18,6 @@ *******************************************************************************/ package org.eclipse.tycho.targetplatform; -import java.net.URI; import java.util.Collection; import java.util.List; import java.util.Properties; diff --git a/tycho-targetplatform/src/main/java/org/eclipse/tycho/targetplatform/TargetDefinitionFile.java b/tycho-targetplatform/src/main/java/org/eclipse/tycho/targetplatform/TargetDefinitionFile.java index 9c64fe60db..f64418c913 100644 --- a/tycho-targetplatform/src/main/java/org/eclipse/tycho/targetplatform/TargetDefinitionFile.java +++ b/tycho-targetplatform/src/main/java/org/eclipse/tycho/targetplatform/TargetDefinitionFile.java @@ -27,7 +27,6 @@ import java.io.OutputStream; import java.io.StringReader; import java.net.URI; -import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; 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 () -> { }; }