Remove runWithLargeStack and remove some single-use abstractions

--
MOS_MIGRATED_REVID=119188524
diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/AbstractJavaBuilder.java b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/AbstractJavaBuilder.java
index 5e04ffb..c55891a 100644
--- a/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/AbstractJavaBuilder.java
+++ b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/AbstractJavaBuilder.java
@@ -15,9 +15,11 @@
 package com.google.devtools.build.buildjar;
 
 import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableList;
 import com.google.common.io.Files;
+import com.google.devtools.build.buildjar.javac.BlazeJavacMain;
 import com.google.devtools.build.buildjar.javac.JavacRunner;
-import com.google.devtools.build.buildjar.javac.JavacRunnerImpl;
+import com.google.devtools.build.buildjar.javac.plugins.BlazeJavaCompilerPlugin;
 
 import com.sun.tools.javac.main.Main.Result;
 
@@ -45,79 +47,32 @@
   protected boolean debug = false;
 
   /**
-   * Flush the buffers of this JavaBuilder
-   */
-  @SuppressWarnings("unused")  // IOException
-  public synchronized void flush(OutputStream err) throws IOException {
-  }
-
-  /**
-   * Shut this JavaBuilder down
-   */
-  @SuppressWarnings("unused")  // IOException
-  public synchronized void shutdown(OutputStream err) throws IOException {
-  }
-
-  /**
-   * Prepares a compilation run and sets everything up so that the source files
-   * in the build request can be compiled. Invokes compileSources to do the
-   * actual compilation.
-   *
-   * @param build A JavaLibraryBuildRequest request object describing what to
-   *              compile
-   * @param err PrintWriter for logging any diagnostic output
-   */
-  public void compileJavaLibrary(final JavaLibraryBuildRequest build, final OutputStream err)
-      throws Exception {
-    prepareSourceCompilation(build);
-
-    final Exception[] exception = {null};
-    final JavacRunner javacRunner = new JavacRunnerImpl(build.getPlugins());
-    runWithLargeStack(
-        new Runnable() {
-          @Override
-          public void run() {
-            try {
-              internalCompileJavaLibrary(build, javacRunner, err);
-            } catch (Exception e) {
-              exception[0] = e;
-            }
-          }
-        },
-        4L * 1024 * 1024); // 4MB stack
-
-    if (exception[0] != null) {
-      throw exception[0];
-    }
-  }
-
-  /**
-   * Compiles the java files of the java library specified in the build request.<p>
-   * The compilation consists of two parts:<p>
-   * First, javac is invoked directly to compile the java files in the build request.<p>
-   * Second, additional processing is done to the .class files that came out of the compile.<p>
+   * Prepares a compilation run and sets everything up so that the source files in the build request
+   * can be compiled. Invokes compileSources to do the actual compilation.
    *
    * @param build A JavaLibraryBuildRequest request object describing what to compile
    * @param err OutputStream for logging any diagnostic output
    */
-  private void internalCompileJavaLibrary(JavaLibraryBuildRequest build, JavacRunner javacRunner,
-      OutputStream err) throws IOException, JavacException {
-    // result may not be null, in case somebody changes the set of source files
-    // to the empty set
-    Result result = Result.OK;
-    if (!build.getSourceFiles().isEmpty()) {
-      PrintWriter javacErrorOutputWriter = new PrintWriter(err);
-      try {
-        result = compileSources(build, javacRunner, javacErrorOutputWriter);
-      } finally {
-        javacErrorOutputWriter.flush();
-      }
+  public Result compileJavaLibrary(final JavaLibraryBuildRequest build, final OutputStream err)
+      throws Exception {
+    prepareSourceCompilation(build);
+    if (build.getSourceFiles().isEmpty()) {
+      return Result.OK;
     }
-
-    if (!result.isOK()) {
-      throw new JavacException(result);
+    JavacRunner javacRunner =
+        new JavacRunner() {
+          @Override
+          public Result invokeJavac(
+              ImmutableList<BlazeJavaCompilerPlugin> plugins, String[] args, PrintWriter output) {
+            return new BlazeJavacMain(output, plugins).compile(args);
+          }
+        };
+    Result result;
+    try (PrintWriter javacErrorOutputWriter = new PrintWriter(err)) {
+      result = compileSources(build, javacRunner, javacErrorOutputWriter);
     }
     runClassPostProcessing(build);
+    return result;
   }
 
   /**
@@ -152,59 +107,23 @@
   /**
    * Perform the build.
    */
-  public void run(JavaLibraryBuildRequest build, PrintStream err) throws Exception {
-    boolean successful = false;
+  public Result run(JavaLibraryBuildRequest build, PrintStream err) throws Exception {
+    Result result = Result.ERROR;
     try {
-      compileJavaLibrary(build, err);
-      buildJar(build);
-      if (!build.getProcessors().isEmpty()) {
-        if (build.getGeneratedSourcesOutputJar() != null) {
-          buildGensrcJar(build, err);
+      result = compileJavaLibrary(build, err);
+      if (result.isOK()) {
+        buildJar(build);
+        if (!build.getProcessors().isEmpty()) {
+          if (build.getGeneratedSourcesOutputJar() != null) {
+            buildGensrcJar(build, err);
+          }
         }
       }
-      successful = true;
     } finally {
-      build.getDependencyModule().emitDependencyInformation(build.getClassPath(), successful);
+      build.getDependencyModule().emitDependencyInformation(build.getClassPath(), result.isOK());
       build.getProcessingModule().emitManifestProto();
-      shutdown(err);
     }
-  }
-
-  // Utility functions
-
-  /**
-   * Runs "run" in another thread (whose lifetime is contained within the
-   * activation of this function call) using a stack size of 'stackSize' bytes.
-   * Unchecked exceptions thrown by the Runnable will be re-thrown in the main
-   * thread.
-   */
-  private static void runWithLargeStack(final Runnable run, long stackSize) {
-    final Throwable[] unchecked = { null };
-    Thread t = new Thread(null, run, "runWithLargeStack", stackSize);
-    t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
-        @Override
-        public void uncaughtException(Thread t, Throwable e) {
-          unchecked[0] = e;
-        }
-      });
-    t.start();
-    boolean wasInterrupted = false;
-    for (;;) {
-      try {
-        t.join(0);
-        break;
-      } catch (InterruptedException e) {
-        wasInterrupted = true;
-      }
-    }
-    if (wasInterrupted) {
-      Thread.currentThread().interrupt();
-    }
-    if (unchecked[0] instanceof Error) {
-      throw (Error) unchecked[0];
-    } else if (unchecked[0] instanceof RuntimeException) {
-      throw (RuntimeException) unchecked[0];
-    }
+    return result;
   }
 
   /**
diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/BazelJavaBuilder.java b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/BazelJavaBuilder.java
index d7ee1aa..398f0d6 100644
--- a/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/BazelJavaBuilder.java
+++ b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/BazelJavaBuilder.java
@@ -96,15 +96,14 @@
       AbstractJavaBuilder builder = build.getDependencyModule().reduceClasspath()
           ? new ReducedClasspathJavaLibraryBuilder()
           : new SimpleJavaLibraryBuilder();
-      builder.run(build, System.err);
-    } catch (JavacException | InvalidCommandLineException e) {
+      return builder.run(build, System.err).exitCode;
+    } catch (InvalidCommandLineException e) {
       System.err.println(CMDNAME + " threw exception: " + e.getMessage());
       return 1;
     } catch (Exception e) {
       e.printStackTrace();
       return 1;
     }
-    return 0;
   }
 
   /**
diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/JavacException.java b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/JavacException.java
deleted file mode 100644
index 5ad1127..0000000
--- a/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/JavacException.java
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2015 The Bazel Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.devtools.build.buildjar;
-
-import com.google.common.base.Preconditions;
-
-import com.sun.tools.javac.main.Main.Result;
-
-/**
- * Exception used to represent failed javac invocation.
- */
-public final class JavacException extends Exception {
-  public JavacException(Result result) {
-    super("java compilation returned status " + result);
-    Preconditions.checkArgument(!result.isOK());
-  }
-}
diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/ReducedClasspathJavaLibraryBuilder.java b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/ReducedClasspathJavaLibraryBuilder.java
index 9f12705..8c2b28f 100644
--- a/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/ReducedClasspathJavaLibraryBuilder.java
+++ b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/ReducedClasspathJavaLibraryBuilder.java
@@ -63,7 +63,7 @@
     // Compile!
     StringWriter javacOutput = new StringWriter();
     PrintWriter javacOutputWriter = new PrintWriter(javacOutput);
-    Result result = javacRunner.invokeJavac(javacArguments, javacOutputWriter);
+    Result result = javacRunner.invokeJavac(build.getPlugins(), javacArguments, javacOutputWriter);
     javacOutputWriter.close();
 
     // If javac errored out because of missing entries on the classpath, give it another try.
@@ -78,7 +78,7 @@
 
       // Fall back to the regular compile, but add extra checks to catch transitive uses
       javacArguments = makeJavacArguments(build);
-      result = javacRunner.invokeJavac(javacArguments, err);
+      result = javacRunner.invokeJavac(build.getPlugins(), javacArguments, err);
     } else {
       err.print(javacOutput.getBuffer());
     }
diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/SimpleJavaLibraryBuilder.java b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/SimpleJavaLibraryBuilder.java
index b6049bf..6417b47 100644
--- a/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/SimpleJavaLibraryBuilder.java
+++ b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/SimpleJavaLibraryBuilder.java
@@ -37,7 +37,7 @@
   Result compileSources(JavaLibraryBuildRequest build, JavacRunner javacRunner, PrintWriter err)
       throws IOException {
     String[] javacArguments = makeJavacArguments(build, build.getClassPath());
-    return javacRunner.invokeJavac(javacArguments, err);
+    return javacRunner.invokeJavac(build.getPlugins(), javacArguments, err);
   }
 
   @Override
diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/javac/JavacRunner.java b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/javac/JavacRunner.java
index e4045cb..799ff9f 100644
--- a/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/javac/JavacRunner.java
+++ b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/javac/JavacRunner.java
@@ -14,6 +14,9 @@
 
 package com.google.devtools.build.buildjar.javac;
 
+import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.buildjar.javac.plugins.BlazeJavaCompilerPlugin;
+
 import com.sun.tools.javac.main.Main.Result;
 
 import java.io.PrintWriter;
@@ -21,35 +24,9 @@
 /**
  * The JavacRunner is a type that can be used to invoke
  * javac and provides a convenient hook for modifications.
- * It is split in two parts: An interface "JavacRunner" and
- * an implementation of that interface, "JavacRunnerImpl".
- *
- * The type is split in two parts to allow us to load
- * the implementation multiple times in different classloaders.
- * This is neccessary, as a single javac can not run multiple
- * times in parallel. By using different classloaders to load
- * different copies of javac in different JavacRunnerImpls,
- * we can run them in parallel.
- *
- * However, since each JavacRunnerImpl will then be loaded
- * in a different classloader, we then would not be able to
- * refer to it by simply declaring a type as "JavacRunnerImpl",
- * as this refers to the JavacRunnerImpl type loaded with the
- * default classloader. Therefore, we'd have to address each
- * of the different JavacRunnerImpls as "Object" and invoke
- * its method via reflection.
- *
- * We can circumvent this problem by declaring an interface
- * that JavacRunnerImpl implements (i.e. JavacRunner).
- * If we always load this super-interface in the default
- * classloader, and make each JavacRunnerImpl (loaded in its
- * own classloader) implement it, we can refer to the
- * JavacRunnerImpls as "JavacRunner"s in the main program.
- * That way, we can avoid using reflection and "Object"
- * to deal with the different JavacRunnerImpls.
  */
 public interface JavacRunner {
 
-  Result invokeJavac(String[] args, PrintWriter output);
-
+  Result invokeJavac(
+      ImmutableList<BlazeJavaCompilerPlugin> plugins, String[] args, PrintWriter output);
 }
diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/javac/JavacRunnerImpl.java b/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/javac/JavacRunnerImpl.java
deleted file mode 100644
index f3eb689..0000000
--- a/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/javac/JavacRunnerImpl.java
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2014 The Bazel Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//    http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.devtools.build.buildjar.javac;
-
-import com.google.devtools.build.buildjar.javac.plugins.BlazeJavaCompilerPlugin;
-
-import com.sun.tools.javac.main.Main.Result;
-
-import java.io.PrintWriter;
-import java.util.List;
-
-/**
- * This class wraps a single invocation of Javac. We
- * invoke javac statically but wrap it with a synchronization.
- * This is because the same javac cannot be invoked multiple
- * times in parallel.
- */
-public class JavacRunnerImpl implements JavacRunner {
-
-  private final List<BlazeJavaCompilerPlugin> plugins;
-
-  /**
-   * Passes extra information to BlazeJavacMain in case strict Java
-   * dependencies are enforced.
-   */
-  public JavacRunnerImpl(List<BlazeJavaCompilerPlugin> plugins) {
-    this.plugins = plugins;
-  }
-
-  @Override
-  public synchronized Result invokeJavac(String[] args, PrintWriter output) {
-    return new BlazeJavacMain(output, plugins).compile(args);
-  }
-
-}