void start()

in src/main/java/com/spotify/fmt/ForkingExecutor.java [165:205]


    void start() {
      if (process != null) {
        throw new IllegalStateException();
      }
      log.debug("serializing closure");
      try {
        Serialization.serialize(f, closureFile);
      } catch (SerializationException e) {
        throw new RuntimeException("Failed to serialize closure", e);
      }

      final String classPathArg = String.join(File.pathSeparator, classpath);

      final ProcessBuilder processBuilder =
          new ProcessBuilder(java.toString(), "-cp", classPathArg).directory(workdir.toFile());

      // Custom jvm args
      javaArgs.forEach(processBuilder.command()::add);

      // Trampoline arguments
      processBuilder.command().add(Trampoline.class.getName());
      processBuilder.command().add(closureFile.toString());
      processBuilder.command().add(resultFile.toString());
      processBuilder.command().add(errorFile.toString());

      processBuilder.environment().putAll(environment);

      log.debug(
          MessageFormat.format(
              "Starting subprocess: environment={0}, command={1}, directory={2}",
              processBuilder.environment(), processBuilder.command(), processBuilder.directory()));
      try {
        process = processBuilder.start();
      } catch (IOException e) {
        throw new RuntimeException(e);
      }

      // Copy std{err,out} line by line to avoid interleaving and corrupting line contents.
      executor.submit(() -> copyLines(process.getInputStream(), System.out));
      executor.submit(() -> copyLines(process.getErrorStream(), System.err));
    }