private Process startDaemonProcess()

in client/src/main/java/org/mvndaemon/mvnd/client/DaemonConnector.java [337:485]


    private Process startDaemonProcess(String daemonId, ClientOutput output) {
        final Path mvndHome = parameters.mvndHome();
        final Path workingDir = parameters.userDir();
        String command = "";
        try {
            List<String> args = new ArrayList<>();
            // executable
            final String java = Os.current().isUnixLike() ? "bin/java" : "bin\\java.exe";
            args.add(parameters.javaHome().resolve(java).toString());
            // classpath
            String mvndAgentPath = null;
            String plexusClassworldsPath = null;
            try (DirectoryStream<Path> jarPaths = Files.newDirectoryStream(
                    mvndHome.resolve("mvn").resolve("lib").resolve("mvnd"))) {
                for (Path jar : jarPaths) {
                    String s = jar.getFileName().toString();
                    if (s.endsWith(".jar")) {
                        if (s.startsWith("mvnd-agent-")) {
                            mvndAgentPath = jar.toString();
                        }
                    }
                }
            }
            try (DirectoryStream<Path> jarPaths =
                    Files.newDirectoryStream(mvndHome.resolve("mvn").resolve("boot"))) {
                for (Path jar : jarPaths) {
                    String s = jar.getFileName().toString();
                    if (s.endsWith(".jar")) {
                        if (s.startsWith("plexus-classworlds-")) {
                            plexusClassworldsPath = jar.toString();
                        }
                    }
                }
            }
            if (mvndAgentPath == null) {
                throw new IllegalStateException("Could not find mvnd-agent jar in mvn/lib/mvnd/");
            }
            if (plexusClassworldsPath == null) {
                throw new IllegalStateException("Could not find plexus-classworlds jar in boot/");
            }
            args.add("-classpath");
            args.add(plexusClassworldsPath);
            args.add("-javaagent:" + mvndAgentPath);
            // debug options
            if (parameters.property(Environment.MVND_DEBUG).asBoolean()) {
                String address =
                        parameters.property(Environment.MVND_DEBUG_ADDRESS).asString();
                String host;
                String port;
                int column = address.indexOf(':');
                if (column >= 0) {
                    host = address.substring(0, column);
                    port = address.substring(column + 1);
                } else {
                    host = "localhost";
                    port = address;
                }
                if (!port.matches("[0-9]+")) {
                    throw new IllegalArgumentException("Wrong debug address syntax: " + address);
                }
                int iPort = Integer.parseInt(port);
                if (iPort == 0) {
                    try (ServerSocketChannel channel = SocketFamily.inet.openServerSocket()) {
                        iPort = ((InetSocketAddress) channel.getLocalAddress()).getPort();
                    } catch (IOException e) {
                        throw new IllegalStateException("Unable to find a free debug port", e);
                    }
                }
                address = host + ":" + iPort;
                output.accept(Message.buildStatus("Daemon listening for debugger on address: " + address));
                args.add("-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=" + address);
            }
            // jvm args
            String jvmArgs = parameters.jvmArgs();
            if (jvmArgs != null) {
                for (String arg : jvmArgs.split(" ")) {
                    if (!arg.isEmpty()) {
                        args.add(arg);
                    }
                }
            }
            // memory
            String minHeapSize = parameters.minHeapSize();
            if (minHeapSize != null) {
                args.add("-Xms" + minHeapSize);
            }
            String maxHeapSize = parameters.maxHeapSize();
            if (maxHeapSize != null) {
                args.add("-Xmx" + maxHeapSize);
            }
            String threadStackSize = parameters.threadStackSize();
            if (threadStackSize != null) {
                args.add("-Xss" + threadStackSize);
            }

            Environment.MVND_HOME.addSystemProperty(args, mvndHome.toString());
            args.add("-Dmaven.home=" + mvndHome.resolve("mvn"));
            args.add("-Dmaven.conf=" + mvndHome.resolve("mvn").resolve("conf"));
            args.add("-Dclassworlds.conf=" + mvndHome.resolve("bin").resolve("mvnd-daemon.conf"));

            args.add("-D" + SimpleLogger.LOG_FILE_KEY + "="
                    + parameters.daemonStorage().resolve("daemon-" + daemonId + ".log"));

            Environment.MVND_JAVA_HOME.addSystemProperty(
                    args, parameters.javaHome().toString());
            Environment.MVND_ID.addSystemProperty(args, daemonId);
            Environment.MVND_DAEMON_STORAGE.addSystemProperty(
                    args, parameters.daemonStorage().toString());
            Environment.MVND_REGISTRY.addSystemProperty(
                    args, parameters.registry().toString());
            Environment.MVND_SOCKET_FAMILY.addSystemProperty(
                    args,
                    parameters
                            .socketFamily()
                            .orElseGet(() -> getJavaVersion() >= 16.0f ? SocketFamily.unix : SocketFamily.inet)
                            .toString());
            parameters.discriminatingSystemProperties(args);
            args.add("org.codehaus.plexus.classworlds.launcher.Launcher");
            command = String.join(" ", args);

            LOGGER.debug(
                    "Starting daemon process: id = {}, workingDir = {}, daemonArgs: {}", daemonId, workingDir, command);
            Path daemonOutLog = parameters.daemonOutLog(daemonId);
            Files.writeString(
                    daemonOutLog,
                    "Starting daemon process: id = " + daemonId + ", workingDir = " + workingDir + ", daemonArgs: "
                            + command,
                    StandardOpenOption.CREATE,
                    StandardOpenOption.APPEND);
            ProcessBuilder.Redirect redirect = ProcessBuilder.Redirect.appendTo(daemonOutLog.toFile());
            ProcessBuilder processBuilder = new ProcessBuilder();
            processBuilder
                    .environment()
                    .put(Environment.JDK_JAVA_OPTIONS.getEnvironmentVariable(), parameters.jdkJavaOpts());
            Process process = processBuilder
                    .directory(workingDir.toFile())
                    .command(args)
                    .redirectOutput(redirect)
                    .redirectError(redirect)
                    .start();
            return process;
        } catch (Exception e) {
            throw new DaemonException.StartException(
                    String.format(
                            "Error starting daemon: id = %s, workingDir = %s, daemonArgs: %s",
                            daemonId, workingDir, command),
                    e);
        }
    }