Fix the deadlock while running compiler.

..also increases the benchmark execution count to reduce the noise.

Change-Id: I188ee7d3c4c2505fa100a6a65b6cf5ef41437a34
diff --git a/benchmarks/src/main/java/com/google/gwt/benchmark/framework/shared/BenchmarkExecutor.java b/benchmarks/src/main/java/com/google/gwt/benchmark/framework/shared/BenchmarkExecutor.java
index f76a463..9a74bb3 100644
--- a/benchmarks/src/main/java/com/google/gwt/benchmark/framework/shared/BenchmarkExecutor.java
+++ b/benchmarks/src/main/java/com/google/gwt/benchmark/framework/shared/BenchmarkExecutor.java
@@ -37,7 +37,7 @@
     runBenchmarkForAtLeast(benchmark, 100, 2);
 
     // At least 2 seconds and 2 runs
-    BenchmarkResult benchmarkResult = runBenchmarkForAtLeast(benchmark, 2000, 2);
+    BenchmarkResult benchmarkResult = runBenchmarkForAtLeast(benchmark, 4000, 10);
     benchmark.tearDownOneTime();
 
     return benchmarkResult;
diff --git a/cli/src/main/java/com/google/j2cl/benchmark/cli/CliInteractor.java b/cli/src/main/java/com/google/j2cl/benchmark/cli/CliInteractor.java
index a3f0fd8..44c6c5f 100644
--- a/cli/src/main/java/com/google/j2cl/benchmark/cli/CliInteractor.java
+++ b/cli/src/main/java/com/google/j2cl/benchmark/cli/CliInteractor.java
@@ -23,7 +23,7 @@
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.InputStream;
+import java.io.StringWriter;
 import java.util.Properties;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -80,7 +80,7 @@
     String outputDir = compilerOutputDir.getAbsolutePath();
     try {
       runCommand(compileScript.getAbsolutePath() + " " + moduleName + " " + devJar.getAbsolutePath()
-          + " " + userJar.getAbsolutePath() + " " + bsl + " " + outputDir + " " + extraArgs, false);
+          + " " + userJar.getAbsolutePath() + " " + bsl + " " + outputDir + " " + extraArgs);
     } catch (CliException e) {
       throw new CliException("failed compile", e);
     }
@@ -146,32 +146,35 @@
   }
 
   private String runCommand(String command) throws CliException {
-    return runCommand(command, true);
-  }
-
-  private String runCommand(String command, boolean useErrorSteam)
-      throws CliException {
-    InputStream stream = null;
     try {
-      Process process = Runtime.getRuntime().exec(command);
-      int exitValue = process.waitFor();
+      final Process process =
+          new ProcessBuilder(command.split(" ")).redirectErrorStream(true).start();
 
+      final StringWriter output = new StringWriter();
+      Thread thread = new Thread(new Runnable() {
+        @Override
+        public void run() {
+          try {
+            IOUtils.copy(process.getInputStream(), output);
+          } catch (IOException e) {
+            e.printStackTrace();
+          }
+        }
+      });
+      thread.start();
+
+      int exitValue = process.waitFor();
       if (exitValue != 0) {
-        stream = useErrorSteam ? process.getErrorStream() : process.getInputStream();
-        String error =
-            "Command returned with " + exitValue + " " + IOUtils.toString(stream, "UTF-8");
-        logger.warning(error);
-        throw new CliException(error);
+        thread.join();
+        logger.warning("Command returned with " + exitValue + " " + output);
+        throw new CliException("Command returned with " + exitValue);
       }
 
-      stream = process.getInputStream();
-      return IOUtils.toString(stream, "UTF-8");
+      return output.toString();
 
     } catch (IOException | InterruptedException e) {
       logger.log(Level.WARNING, "Can not run command", e);
       throw new CliException("Can not run command");
-    } finally {
-      IOUtils.closeQuietly(stream);
     }
   }
 }