private static Integer startAndWaitImpl()

in java/com/jetbrains/cef/remote/ServerStarter.java [300:412]


    private static Integer startAndWaitImpl(File serverExe, ThriftTransport thriftServer, CefAppHandler appHandler, String[] args, CefSettings settings, String logPath, String logLevel, boolean deleteRootDir, Map<String, String> env, long timeoutMs) {
        final long t0 = System.nanoTime();
        CefLog.Info("Start native cef_server with cache path: %s", settings == null ? null : settings.cache_path);
        CefLog.Debug("cef_server executable path='%s'", serverExe.getAbsolutePath());

        if (ourNativeServerProcesses.get(thriftServer.toString()) != null)
            CefLog.Debug("Handle of server process will be overwritten.");
        ourNativeServerProcesses.remove(thriftServer.toString());

        ProcessBuilder builder = new ProcessBuilder(serverExe.getAbsolutePath());
        CefLog.Debug("\tWorking dir %s", serverExe.getParentFile());
        builder.directory(serverExe.getParentFile());
        builder.redirectOutput(ProcessBuilder.Redirect.INHERIT);
        builder.redirectError(ProcessBuilder.Redirect.INHERIT);

        if (env != null && env.size() > 0) {
            builder.environment().putAll(env);
            if (CefLog.IsDebugEnabled()) {
                String logTxt = "";
                for (Map.Entry<String, String> entry : env.entrySet()) {
                    if (logTxt.length() > 0)
                        logTxt += "; ";
                    logTxt += entry.getKey() + "=" + entry.getValue();
                }
                CefLog.Debug("\tEnvironment vars: %s", logTxt);
            }
        }

        if (thriftServer.isTcp()) {
            CefLog.Debug("\tUse tcp-port %d", thriftServer.getPort());
            builder.command().add(String.format("--port=%d", thriftServer.getPort()));
        } else {
            CefLog.Debug("\tUse pipe %s", thriftServer.getPipe());
            builder.command().add(String.format("--pipe=%s", thriftServer.getPipe()));
        }
        String logStream = "stderr";
        if (logPath != null && !logPath.isEmpty()) {
            logStream = "file '" + logPath + "'";
            builder.command().add(String.format("--logfile=%s", logPath.trim()));
        }

        CefLog.Info("Native server logging: level '%s', stream: '%s'", logLevel, logStream);
        builder.command().add(String.format("--loglevel=%s", logLevel));

        if (System.getenv().containsKey("DEBUG_CEF_SERVER"))
            builder.command().add("--cef-server-wait-debugger");

        if (deleteRootDir)
            builder.command().add("--deleteRootCacheDir");

        if (!USE_PARAMS_FILE
                || !prepareStartParamsWithFile(builder, serverExe, appHandler, args, settings))
        {
            prepareStartParamsWithCmdLine(builder, serverExe, appHandler, args, settings);
        }

        Process p;
        try {
            p = builder.start();
            ourNativeServerProcesses.put(thriftServer.toString(), p);
        } catch (Throwable e) {
            CefLog.Error("Can't start native cef_server, exception: %s", e.getMessage());
            return Integer.MIN_VALUE;
        }

        // Wait for native server
        Integer exitVal = null;
        boolean running = false;
        final long t1 = System.nanoTime();
        do {
            try {
                Thread.sleep(WAIT_START_LOOP_SLEEP_MS);
            } catch (InterruptedException e) {
                CefLog.Error("Exception during waiting for native cef_server: %s", e.getMessage());
            }
            CefLog.Debug("Waiting for server %s starting...", thriftServer.toStringShort());
            // 1. Check process exit values.
            try {
                exitVal = p.exitValue();
            } catch (IllegalThreadStateException e) {}

            if (exitVal != null) {
                CefLog.Error("Native cef_server exited with code %d", exitVal);
                if (exitVal == 100) {
                    CefLog.Error("It means that cef_server can't load CEF framework library.");
                } else if (exitVal == 101) {
                    CefLog.Error("It means that CefInitialize returns false - probably, JCEF cache dir is locked.");
                    // TODO: search stdout for string 'Opening in existing browser session'
                }

                ourNativeServerProcesses.remove(thriftServer.toString());
                return exitVal;
            }

            // 2. Try to connect with cef_server.
            running = NativeServerManager.isRunning(thriftServer) != null;
        } while (!running && (System.nanoTime() - t1 < timeoutMs*1000000));

        // Check whether the server is running or not.
        if (!running && !(running = (NativeServerManager.isRunning(thriftServer, true) != null))) {
            if (p.isAlive())
                CefLog.Error("Native cef_server was started but client can't connect.");
            else {
                CefLog.Error("Can't start native cef_server, process is dead.");
                ourNativeServerProcesses.remove(thriftServer.toString());
            }
            try {
                exitVal = p.exitValue();
            } catch (IllegalThreadStateException e) {}
        } else
            CefLog.Debug("Server is started. Spent ms: process starting %d, waiting %d", (t1 - t0)/1000000, (System.nanoTime() - t1)/1000000);
        return running ? null : exitVal;
    }