mirror of
https://github.com/apache/maven-mvnd.git
synced 2025-10-15 14:50:54 +00:00
Allow unix domain sockets for client/daemon connection (not used by default)
This commit is contained in:
@@ -16,9 +16,9 @@
|
||||
package org.mvndaemon.mvnd.client;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.io.IOException;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.StandardProtocolFamily;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.nio.file.Files;
|
||||
@@ -32,6 +32,7 @@ import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
import java.util.Random;
|
||||
import java.util.Scanner;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -49,6 +50,7 @@ import org.mvndaemon.mvnd.common.Environment;
|
||||
import org.mvndaemon.mvnd.common.MavenDaemon;
|
||||
import org.mvndaemon.mvnd.common.Message;
|
||||
import org.mvndaemon.mvnd.common.Os;
|
||||
import org.mvndaemon.mvnd.common.SocketHelper;
|
||||
import org.mvndaemon.mvnd.common.logging.ClientOutput;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -371,6 +373,10 @@ public class DaemonConnector {
|
||||
Environment.MVND_ID.addCommandLineOption(args, daemonId);
|
||||
Environment.MVND_DAEMON_STORAGE.addCommandLineOption(args, parameters.daemonStorage().toString());
|
||||
Environment.MVND_REGISTRY.addCommandLineOption(args, parameters.registry().toString());
|
||||
Environment.MVND_SOCKET_FAMILY.addCommandLineOption(args,
|
||||
parameters.socketFamily().orElseGet(
|
||||
() -> getJavaVersion() >= 16.0f ? StandardProtocolFamily.UNIX : StandardProtocolFamily.INET)
|
||||
.toString());
|
||||
parameters.discriminatingCommandLineOptions(args);
|
||||
args.add(MavenDaemon.class.getName());
|
||||
command = String.join(" ", args);
|
||||
@@ -394,6 +400,31 @@ public class DaemonConnector {
|
||||
}
|
||||
}
|
||||
|
||||
private float getJavaVersion() {
|
||||
try {
|
||||
final String java = Os.current().isUnixLike() ? "bin/java" : "bin\\java.exe";
|
||||
Path javaExec = parameters.javaHome().resolve(java);
|
||||
List<String> args = new ArrayList<>();
|
||||
args.add(javaExec.toString());
|
||||
args.add("-version");
|
||||
Process process = new ProcessBuilder()
|
||||
.directory(parameters.mvndHome().toFile())
|
||||
.command(args)
|
||||
.start();
|
||||
process.waitFor();
|
||||
Scanner sc = new Scanner(process.getErrorStream());
|
||||
sc.next();
|
||||
sc.next();
|
||||
String version = sc.next();
|
||||
LOGGER.warn("JAVA VERSION: " + version);
|
||||
int is = version.charAt(0) == '"' ? 1 : 0;
|
||||
int ie = version.indexOf('.', version.indexOf('.', is));
|
||||
return Float.parseFloat(version.substring(is, ie));
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Unable to detect java version", e);
|
||||
}
|
||||
}
|
||||
|
||||
private DaemonClientConnection connectToDaemonWithId(String daemon, boolean newDaemon)
|
||||
throws DaemonException.ConnectException {
|
||||
// Look for 'our' daemon among the busy daemons - a daemon will start in busy state so that nobody else will
|
||||
@@ -444,18 +475,37 @@ public class DaemonConnector {
|
||||
}
|
||||
}
|
||||
|
||||
public DaemonConnection connect(int port, byte[] token) throws DaemonException.ConnectException {
|
||||
InetSocketAddress address = new InetSocketAddress(InetAddress.getLoopbackAddress(), port);
|
||||
public DaemonConnection connect(String str, byte[] token) throws DaemonException.ConnectException {
|
||||
SocketAddress address = SocketHelper.socketAddressFromString(str);
|
||||
StandardProtocolFamily family = SocketHelper.getSocketFamily(address);
|
||||
try {
|
||||
LOGGER.debug("Trying to connect to address {}.", address);
|
||||
SocketChannel socketChannel = SocketChannel.open();
|
||||
Socket socket = socketChannel.socket();
|
||||
socket.connect(address, CONNECT_TIMEOUT);
|
||||
if (socket.getLocalSocketAddress().equals(socket.getRemoteSocketAddress())) {
|
||||
socketChannel.close();
|
||||
throw new DaemonException.ConnectException(String.format("Socket connected to itself on %s.", address));
|
||||
SocketChannel socketChannel = SocketHelper.openSocket(family);
|
||||
socketChannel.configureBlocking(false);
|
||||
boolean connected = socketChannel.connect(address);
|
||||
if (!connected) {
|
||||
long t0 = System.nanoTime();
|
||||
long t1 = t0 + TimeUnit.MICROSECONDS.toNanos(CONNECT_TIMEOUT);
|
||||
while (!connected && t0 < t1) {
|
||||
Thread.sleep(10);
|
||||
connected = socketChannel.finishConnect();
|
||||
if (!connected) {
|
||||
t0 = System.nanoTime();
|
||||
}
|
||||
}
|
||||
if (!connected) {
|
||||
throw new IOException("Timeout");
|
||||
}
|
||||
}
|
||||
LOGGER.debug("Connected to address {}.", socket.getRemoteSocketAddress());
|
||||
socketChannel.configureBlocking(true);
|
||||
|
||||
// Socket socket = socketChannel.socket();
|
||||
// socket.connect(address, CONNECT_TIMEOUT);
|
||||
// if (socket.getLocalSocketAddress().equals(socket.getRemoteSocketAddress())) {
|
||||
// socketChannel.close();
|
||||
// throw new DaemonException.ConnectException(String.format("Socket connected to itself on %s.", address));
|
||||
// }
|
||||
LOGGER.debug("Connected to address {}.", socketChannel.getRemoteAddress());
|
||||
|
||||
ByteBuffer tokenBuffer = ByteBuffer.wrap(token);
|
||||
do {
|
||||
|
@@ -18,6 +18,7 @@ package org.mvndaemon.mvnd.client;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.StandardProtocolFamily;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
@@ -323,6 +324,10 @@ public class DaemonParameters {
|
||||
return property(Environment.MVND_LOG_PURGE_PERIOD).orFail().asDuration();
|
||||
}
|
||||
|
||||
public Optional<StandardProtocolFamily> socketFamily() {
|
||||
return property(Environment.MVND_SOCKET_FAMILY).asOptional().map(StandardProtocolFamily::valueOf);
|
||||
}
|
||||
|
||||
public static String findDefaultMultimoduleProjectDirectory(Path pwd) {
|
||||
Path dir = pwd;
|
||||
do {
|
||||
|
Reference in New Issue
Block a user