Skip to content

Commit

Permalink
Fix IpcClient on windows, improve logging
Browse files Browse the repository at this point in the history
  • Loading branch information
gnodet committed Aug 31, 2021
1 parent f450097 commit 07042e7
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 20 deletions.
60 changes: 45 additions & 15 deletions sync/src/main/java/org/mvndaemon/mvnd/sync/IpcClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
import java.net.SocketAddress;
import java.nio.channels.ByteChannel;
Expand Down Expand Up @@ -49,6 +51,7 @@
import java.util.concurrent.atomic.AtomicInteger;
import org.mvndaemon.mvnd.common.ByteChannelWrapper;
import org.mvndaemon.mvnd.common.JavaVersion;
import org.mvndaemon.mvnd.common.Os;
import org.mvndaemon.mvnd.common.SocketFamily;

import static org.mvndaemon.mvnd.sync.IpcMessages.REQUEST_ACQUIRE;
Expand All @@ -65,18 +68,20 @@
*/
public class IpcClient {

Path repository;
Path syncServerPath;
Path lockPath;
Path logPath;
Path syncPath;
SocketChannel socket;
DataOutputStream output;
DataInputStream input;
Thread receiver;
AtomicInteger requestId = new AtomicInteger();
Map<Integer, CompletableFuture<List<String>>> responses = new ConcurrentHashMap<>();

IpcClient(Path repository, Path syncServerPath) {
this.repository = repository;
this.syncServerPath = syncServerPath;
IpcClient(Path lockPath, Path logPath, Path syncPath) {
this.lockPath = lockPath;
this.logPath = logPath;
this.syncPath = syncPath;
}

synchronized void ensureInitialized() throws IOException {
Expand All @@ -97,8 +102,8 @@ SocketChannel createClient() throws IOException {
? SocketFamily.valueOf(familyProp)
: JavaVersion.getJavaSpec() >= 16.0f ? SocketFamily.unix : SocketFamily.inet;

Path lockFile = repository.resolve(".maven-resolver-ipc-lock-" + family.name().toLowerCase())
.toAbsolutePath().normalize();
Path lockPath = this.lockPath.toAbsolutePath().normalize();
Path lockFile = lockPath.resolve(".maven-resolver-ipc-lock-" + family.name().toLowerCase());
if (!Files.isRegularFile(lockFile)) {
if (!Files.isDirectory(lockFile.getParent())) {
Files.createDirectories(lockFile.getParent());
Expand All @@ -125,16 +130,18 @@ SocketChannel createClient() throws IOException {
boolean win = System.getProperty("os.name").toLowerCase(Locale.ROOT).contains("win");
if (!noNative) {
String syncCmd = win ? "mvnd-sync.exe" : "mvnd-sync";
noNative = !Files.isExecutable(syncServerPath.resolve(syncCmd));
noNative = !Files.isExecutable(syncPath.resolve(syncCmd));
}
Closeable close;
Path logFile = logPath.resolve("mvnd-sync-" + rand + ".log");
List<String> args = null;
if (noNative) {
String noFork = System.getProperty(IpcServer.NO_FORK_PROP);
if (Boolean.parseBoolean(noFork)) {
IpcServer server = IpcServer.runServer(family, tmpaddr, rand);
close = server::close;
} else {
List<String> args = new ArrayList<>();
args = new ArrayList<>();
String javaHome = System.getenv("JAVA_HOME");
if (javaHome == null) {
javaHome = System.getProperty("java.home");
Expand All @@ -156,6 +163,8 @@ SocketChannel createClient() throws IOException {
ProcessBuilder processBuilder = new ProcessBuilder();
ProcessBuilder.Redirect discard = ProcessBuilder.Redirect.to(new File(win ? "NUL" : "/dev/null"));
discard = ProcessBuilder.Redirect.INHERIT;
Files.createDirectories(logPath);
discard = ProcessBuilder.Redirect.to(logFile.toFile());
Process process = processBuilder
.directory(lockFile.getParent().toFile())
.command(args)
Expand All @@ -165,9 +174,9 @@ SocketChannel createClient() throws IOException {
close = process::destroyForcibly;
}
} else {
List<String> args = new ArrayList<>();
args = new ArrayList<>();
String syncCmd = win ? "mvnd-sync.exe" : "mvnd-sync";
args.add(syncServerPath.resolve(syncCmd).toString());
args.add(syncPath.resolve(syncCmd).toString());
String timeout = System.getProperty(IpcServer.IDLE_TIMEOUT_PROP);
if (timeout != null) {
args.add("-D" + IpcServer.IDLE_TIMEOUT_PROP + "=" + timeout);
Expand All @@ -178,6 +187,8 @@ SocketChannel createClient() throws IOException {
ProcessBuilder processBuilder = new ProcessBuilder();
ProcessBuilder.Redirect discard = ProcessBuilder.Redirect.to(new File(win ? "NUL" : "/dev/null"));
discard = ProcessBuilder.Redirect.INHERIT;
Files.createDirectories(logPath);
discard = ProcessBuilder.Redirect.to(logFile.toFile());
Process process = processBuilder
.directory(lockFile.getParent().toFile())
.command(args)
Expand All @@ -199,6 +210,13 @@ SocketChannel createClient() throws IOException {
try {
res = future.get(5, TimeUnit.SECONDS);
} catch (Exception e) {
try (PrintWriter writer = new PrintWriter(new FileWriter(logFile.toFile(), true))) {
writer.println("Arguments:");
args.forEach(writer::println);
writer.println();
writer.println("Exception:");
e.printStackTrace(writer);
}
close.close();
throw e;
} finally {
Expand Down Expand Up @@ -227,12 +245,24 @@ private String getJarPath(Class clazz) {
String className = clazz.getName().replace('.', '/') + ".class";
String url = clazz.getClassLoader().getResource(className).toString();
if (url.startsWith("jar:")) {
classpath = url.substring("jar:".length(), url.indexOf("!/"));
url = url.substring("jar:".length(), url.indexOf("!/"));
if (url.startsWith("file:")) {
classpath = url.substring("file:".length());
} else {
throw new IllegalStateException();
}
} else if (url.startsWith("file:")) {
classpath = url.substring("file:".length(), url.indexOf(className));
} else {
throw new IllegalStateException();
}
if (Os.current() == Os.WINDOWS) {
if (classpath.startsWith("/")) {
classpath = classpath.substring(1);
}
classpath = classpath.replace('/', '\\');
}

return classpath;
}

Expand Down Expand Up @@ -354,9 +384,9 @@ void unlock(String contextId) {
@Override
public String toString() {
return "IpcClient{"
+ "repository=" + repository + ','
+ "address=" + (socket != null ? getAddress() : 0)
+ '}';
+ "lockPath=" + lockPath + ","
+ "syncServerPath=" + syncPath + ","
+ "address='" + getAddress() + "'}";
}

private String getAddress() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.eclipse.aether.SyncContext;
import org.eclipse.aether.impl.SyncContextFactory;
import org.eclipse.sisu.Priority;
import org.mvndaemon.mvnd.common.Environment;

/**
* The SyncContextFactory implementation.
Expand All @@ -40,9 +41,10 @@ public class IpcSyncContextFactory implements SyncContextFactory {
@Override
public SyncContext newInstance(RepositorySystemSession session, boolean shared) {
Path repository = session.getLocalRepository().getBasedir().toPath();
String mvndHome = System.getProperty("mvnd.home");
Path logPath = Environment.MVND_DAEMON_STORAGE.asPath();
String mvndHome = Environment.MVND_HOME.asOptional().orElse(null);
Path syncPath = mvndHome != null ? Paths.get(mvndHome).resolve("bin") : null;
IpcClient client = clients.computeIfAbsent(repository, r -> new IpcClient(r, syncPath));
IpcClient client = clients.computeIfAbsent(repository, r -> new IpcClient(r, logPath, syncPath));
return new IpcSyncContext(client, shared);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
package org.mvndaemon.mvnd.sync;

import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.eclipse.aether.SyncContext;
Expand All @@ -28,6 +30,7 @@
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.mvndaemon.mvnd.common.Environment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -37,6 +40,9 @@ public class IpcSyncContextTest {

@BeforeAll
static void setup() {
Path target = Paths.get(System.getProperty("basedir", "")).resolve("target");
System.setProperty(Environment.MVND_DAEMON_STORAGE.getProperty(), target.resolve("mvnd/storage").toString());
System.setProperty(Environment.MVND_HOME.getProperty(), target.resolve("mvnd/home").toString());
System.setProperty(IpcServer.IDLE_TIMEOUT_PROP, "5");
System.setProperty(IpcServer.FAMILY_PROP, "inet");
System.setProperty(IpcServer.NO_NATIVE_PROP, "true");
Expand All @@ -52,7 +58,7 @@ public void testContextSimple() throws Exception {
SyncContextFactory factory = new IpcSyncContextFactory();

DefaultRepositorySystemSession session = new DefaultRepositorySystemSession();
LocalRepository repository = new LocalRepository(new File("target/test-repo"));
LocalRepository repository = new LocalRepository(new File("target/mvnd/test-repo"));
LocalRepositoryManager localRepositoryManager = new SimpleLocalRepositoryManagerFactory()
.newInstance(session, repository);
session.setLocalRepositoryManager(localRepositoryManager);
Expand All @@ -69,7 +75,7 @@ public void testContext() throws Exception {
SyncContextFactory factory = new IpcSyncContextFactory();

DefaultRepositorySystemSession session = new DefaultRepositorySystemSession();
LocalRepository repository = new LocalRepository(new File("target/test-repo"));
LocalRepository repository = new LocalRepository(new File("target/mvnd/test-repo"));
LocalRepositoryManager localRepositoryManager = new SimpleLocalRepositoryManagerFactory()
.newInstance(session, repository);
session.setLocalRepositoryManager(localRepositoryManager);
Expand Down Expand Up @@ -107,7 +113,7 @@ void testTimeoutAndConnect() throws Exception {
SyncContextFactory factory = new IpcSyncContextFactory();

DefaultRepositorySystemSession session = new DefaultRepositorySystemSession();
LocalRepository repository = new LocalRepository(new File("target/test-repo"));
LocalRepository repository = new LocalRepository(new File("target/mvnd/test-repo"));
LocalRepositoryManager localRepositoryManager = new SimpleLocalRepositoryManagerFactory()
.newInstance(session, repository);
session.setLocalRepositoryManager(localRepositoryManager);
Expand Down

0 comments on commit 07042e7

Please sign in to comment.