public static void startDiffProcess(
      File differExe, String primaryExportedName, String secondaryExportedName, File outputDir)
      throws DifferException {
    final ProcessBuilder processBuilder =
        new ProcessBuilder(
            differExe.getPath(),
            "--nologo",
            "--primary=" + primaryExportedName,
            "--secondary=" + secondaryExportedName,
            "--output_dir=" + outputDir.getPath(),
            "--output_format=bin");
    int exitCode = -1;

    ProcessOutputStreamReader s1 = null;
    ProcessOutputStreamReader s2 = null;
    try {
      processBuilder.redirectErrorStream(true);
      logger.atFinest().log(
          "%s",
          processBuilder.command().stream()
              .map(s -> (!s.contains(" ") ? s : "\"" + s + "\""))
              .collect(joining(" ")));
      final Process diffProcess = processBuilder.start();

      // This is needed to avoid a deadlock!
      // More information see:
      // http://www.javakb.com/Uwe/Forum.aspx/java-programmer/7243/Process-waitFor-vs-Process-destroy
      s1 = new ProcessOutputStreamReader("BinDiff - stdout", diffProcess.getInputStream());
      s2 = new ProcessOutputStreamReader("BinDiff - stderr", diffProcess.getErrorStream());
      s1.start();
      s2.start();

      exitCode = diffProcess.waitFor();

      s1.interruptThread();
      s2.interruptThread();

      handleExitCode(exitCode);
    } catch (IOException e) {
      throw new DifferException(
          e, String.format("Couldn't start diffing process. Exit code %d.", exitCode));
    } catch (InterruptedException e) {
      throw new DifferException(
          e,
          String.format("Diffing process was interrupted unexpectedly. Exit code %d.", exitCode));
    } catch (Exception e) {
      throw new DifferException(
          e, String.format("Diffing process failed. Exit code %d.", exitCode));
    } finally {
      if (s1 != null) {
        s1.interruptThread();
      }
      if (s2 != null) {
        s2.interruptThread();
      }
    }
  }
Creates a fully specified filename no longer than 250 characters.

<p>It should behave exactly the same as the engine's main_portable.cc version. Note: path must
include a trailing slash, extension needs to start with a dot.
java/ui/src/main/java/com/google/security/zynamics/bindiff/processes/DiffProcess.java