Skip to content

Commit

Permalink
Backport filelocker and some style changes to sync with master
Browse files Browse the repository at this point in the history
  • Loading branch information
laeubi committed Dec 11, 2023
1 parent 907d87c commit 1f81c3f
Show file tree
Hide file tree
Showing 50 changed files with 377 additions and 411 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/maven.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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') }}
Expand All @@ -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 }}
Expand All @@ -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 }}
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public void setHeader(String key, String value) {
public Response<InputStream> get() throws IOException {
HttpURLConnection connection = createConnection();
connection.connect();
return new HttpResponse<InputStream>(connection) {
return new HttpResponse<>(connection) {

@Override
public void close() {
Expand Down Expand Up @@ -111,7 +111,7 @@ public Response<Void> head() throws IOException {
HttpURLConnection connection = createConnection();
connection.setRequestMethod("HEAD");
connection.connect();
return new HttpResponse<Void>(connection) {
return new HttpResponse<>(connection) {

@Override
public void close() {
Expand Down
5 changes: 5 additions & 0 deletions sisu-osgi/sisu-osgi-connect/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.platform</groupId>
<artifactId>org.eclipse.equinox.registry</artifactId>
<version>3.11.400</version>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
}
Expand Down Expand Up @@ -238,6 +242,62 @@ private static Map<String, String> 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<IExtensionRegistry, IExtensionRegistry> 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<ServiceComponentRuntime, ServiceComponentRuntime> st = new ServiceTracker<>(
framework.getBundleContext(), ServiceComponentRuntime.class, null);
st.open();
Expand Down Expand Up @@ -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 -> {
Expand Down
26 changes: 21 additions & 5 deletions tycho-api/src/main/java/org/eclipse/tycho/FileLockService.java
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -13,6 +13,7 @@

package org.eclipse.tycho;

import java.io.Closeable;
import java.io.File;

/**
Expand All @@ -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.
* <p>
* This is equivalent to {@link #lock(File, long)} with a timeout argument of 10 seconds.
* </p>
*/
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);
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public void afterProjectsRead(MavenSession session) throws MavenExecutionExcepti
Map<MavenProject, Project> bndProjects = getProjects(session);
Map<String, MavenProject> manifestFirstProjects = getManifestFirstProjects(session, bndProjects.keySet());
Map<String, MavenProject> bndWorkspaceProjects = bndProjects.entrySet().stream()
.collect(Collectors.toMap(e -> e.getValue().getName(), e -> e.getKey(), (a, b) -> {
.collect(Collectors.toMap(e -> e.getValue().getName(), Entry<MavenProject, Project>::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());
Expand Down Expand Up @@ -166,8 +166,8 @@ private Map<String, MavenProject> getManifestFirstProjects(MavenSession session,
}

private Map<MavenProject, Project> getProjects(MavenSession session) {
Set<Workspace> workspaces = new HashSet<Workspace>();
HashMap<MavenProject, Project> result = new HashMap<MavenProject, Project>();
Set<Workspace> workspaces = new HashSet<>();
HashMap<MavenProject, Project> result = new HashMap<>();
for (MavenProject mavenProject : session.getProjects()) {
if (isBNDProject(mavenProject)) {
try {
Expand Down Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,6 @@ public abstract class AbstractOsgiCompilerMojo extends AbstractCompilerMojo impl
* And a configuration:
*
* &lt;configuration&gt;
* &lt;logEnabled&gt;true&lt;/logEnabled&gt;
* &lt;logDirectory&gt;${project.build.directory}/logfiles&lt;/logDirectory&gt;
* &lt;log&gt;xml&lt;/log&gt;
* &lt;/configuration&gt;
Expand Down Expand Up @@ -883,12 +882,12 @@ private ExecutionEnvironment getTargetExecutionEnvironment() {

@Override
public List<ClasspathEntry> getClasspath() throws MojoExecutionException {
ReactorProject reactorProject = DefaultReactorProject.adapt(project);
List<ClasspathEntry> 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) {
Expand Down Expand Up @@ -940,7 +939,7 @@ public List<ClasspathEntry> getClasspath() throws MojoExecutionException {
}
}
}
List<ClasspathEntry> uniqueClasspath = classpathMap.entrySet().stream().flatMap(entry -> {
return classpathMap.entrySet().stream().flatMap(entry -> {
List<ClasspathEntry> list = entry.getValue();
if (list.isEmpty()) {
return Stream.empty();
Expand All @@ -949,7 +948,7 @@ public List<ClasspathEntry> getClasspath() throws MojoExecutionException {
return list.stream();
}
ArtifactKey key = entry.getKey();
ReactorProject compositeProject = findProjectForKey(reactorProject, key);
ReactorProject compositeProject = findProjectForKey(key);
List<File> compositeFiles = list.stream().flatMap(cpe -> cpe.getLocations().stream()).toList();
Collection<AccessRule> compositeRules = mergeRules(list);
return Stream.of(new ClasspathEntry() {
Expand Down Expand Up @@ -984,7 +983,6 @@ public String toString() {

});
}).toList();
return uniqueClasspath;
}

private ArtifactKey normalizedKey(ArtifactKey key) {
Expand Down Expand Up @@ -1014,7 +1012,7 @@ private Collection<AccessRule> mergeRules(List<ClasspathEntry> 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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,7 @@ public Collection<IInstallableUnit> getInstallableUnits(MavenProject project, Ma
Version version = new MavenVersion(project.getVersion()).getOSGiVersion();
pr.setProperty(Constants.BUNDLE_VERSION, version.toString());
}
Collection<Dependency> dependencies = collectInitial(project, new HashMap<String, Dependency>())
.values();
Collection<Dependency> 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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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<Path, FileLocks> lockers = new ConcurrentHashMap<>();

private final Map<String, FileLockerImpl> 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()));
}

}
Loading

0 comments on commit 1f81c3f

Please sign in to comment.