Report a proper error when the JDT compiler aborts.

That is, print the file and line where the internal error happened, instead of
spurious, nondeterministic errors about being unable to find java/lang/Object
and so on. Once the file is identified it's possible to work around it;
sometimes GWT doesn't need to compile the file at all.

Also added JavaDoc on some methods.

Change-Id: I74397bfa2be4e75ec116f42611197a7fa3953701
Review-Link: https://gwt-review.googlesource.com/#/c/2090/

Review by: mdempsky@google.com

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@11542 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/javac/CompilationState.java b/dev/core/src/com/google/gwt/dev/javac/CompilationState.java
index 9a854e1..5e8844c 100644
--- a/dev/core/src/com/google/gwt/dev/javac/CompilationState.java
+++ b/dev/core/src/com/google/gwt/dev/javac/CompilationState.java
@@ -16,6 +16,7 @@
 package com.google.gwt.dev.javac;
 
 import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
 import com.google.gwt.dev.javac.CompilationStateBuilder.CompileMoreLater;
 import com.google.gwt.dev.javac.typemodel.TypeOracle;
 import com.google.gwt.dev.util.log.speedtracer.DevModeEventType;
@@ -82,8 +83,13 @@
     assimilateUnits(logger, units);
   }
 
+  /**
+   * Compiles the given source files (unless cached) and adds them to the
+   * CompilationState.
+   * If the the compiler aborts, logs the error and throws UnableToCompleteException.
+   */
   public void addGeneratedCompilationUnits(TreeLogger logger,
-      Collection<GeneratedUnit> generatedUnits) {
+      Collection<GeneratedUnit> generatedUnits) throws UnableToCompleteException {
     Event generatedUnitsAddEvent = SpeedTracerLogger.start(
         DevModeEventType.COMP_STATE_ADD_GENERATED_UNITS);
     try {
diff --git a/dev/core/src/com/google/gwt/dev/javac/CompilationStateBuilder.java b/dev/core/src/com/google/gwt/dev/javac/CompilationStateBuilder.java
index 7781753..99c3770 100644
--- a/dev/core/src/com/google/gwt/dev/javac/CompilationStateBuilder.java
+++ b/dev/core/src/com/google/gwt/dev/javac/CompilationStateBuilder.java
@@ -16,6 +16,7 @@
 package com.google.gwt.dev.javac;
 
 import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
 import com.google.gwt.dev.javac.JdtCompiler.AdditionalTypeProviderDelegate;
 import com.google.gwt.dev.javac.JdtCompiler.UnitProcessor;
 import com.google.gwt.dev.jjs.CorrelationFactory.DummyCorrelationFactory;
@@ -168,8 +169,13 @@
       this.suppressErrors = suppressErrors;
     }
 
+    /**
+     * Compiles generated source files (unless cached) and adds them to the
+     * CompilationState. If the compiler aborts, logs an error and throws
+     * UnableToCompleteException.
+     */
     public Collection<CompilationUnit> addGeneratedTypes(TreeLogger logger,
-        Collection<GeneratedUnit> generatedUnits) {
+        Collection<GeneratedUnit> generatedUnits) throws UnableToCompleteException {
       Event event = SpeedTracerLogger.start(DevModeEventType.CSB_ADD_GENERATED_TYPES);
       try {
         return doBuildGeneratedTypes(logger, generatedUnits, this, suppressErrors);
@@ -189,10 +195,32 @@
       }
     }
 
+    /**
+     * Compiles the source code in each supplied CompilationUnitBuilder into a CompilationUnit and
+     * reports errors.
+     *
+     * <p>A compilation unit is considered invalid if any of its dependencies (recursively) isn't
+     * being compiled and isn't in allValidClasses, or if it has a signature that doesn't match
+     * a dependency. Valid compilation units will be added to cachedUnits and the unit cache, and
+     * their types will be added to allValidClasses. Invalid compilation units will be removed.</p>
+     *
+     * <p>I/O: serializes the AST of each Java type to DiskCache. (This happens even if the
+     * compilation unit is later dropped.) If we're using the persistent unit cache, each valid
+     * unit will also be serialized to the gwt-unitcache file. (As a result, each AST will be
+     * copied there from the DiskCache.) A new persistent unit cache file will be created
+     * each time compile() is called (if there's at least one valid unit) and the entire cache
+     * will be rewritten to disk every {@link PersistentUnitCache#CACHE_FILE_THRESHOLD} files.</p>
+     *
+     * <p>This function won't report errors in invalid source files unless suppressErrors is false.
+     * Instead, a summary giving the number of invalid files will be logged.</p>
+     *
+     * <p>If the JDT compiler aborts, logs an error and throws UnableToCompleteException. (This
+     * doesn't happen for normal compile errors.)</p>
+     */
     Collection<CompilationUnit> compile(TreeLogger logger,
         Collection<CompilationUnitBuilder> builders,
         Map<CompilationUnitBuilder, CompilationUnit> cachedUnits, EventType eventType,
-        boolean suppressErrors) {
+        boolean suppressErrors) throws UnableToCompleteException {
       // Initialize the set of valid classes to the initially cached units.
       for (CompilationUnit unit : cachedUnits.values()) {
         for (CompiledClass cc : unit.getCompiledClasses()) {
@@ -245,7 +273,7 @@
         Event jdtCompilerEvent = SpeedTracerLogger.start(eventType);
         long compilationStartNanos = System.nanoTime();
         try {
-          compiler.doCompile(builders);
+          compiler.doCompile(branch, builders);
         } finally {
           jdtCompilerEvent.end();
         }
@@ -372,17 +400,24 @@
     }
   }
 
-  public static CompilationState buildFrom(TreeLogger logger, Set<Resource> resources) {
+  public static CompilationState buildFrom(TreeLogger logger, Set<Resource> resources)
+      throws UnableToCompleteException {
     return buildFrom(logger, resources, null, false);
   }
 
   public static CompilationState buildFrom(TreeLogger logger, Set<Resource> resources,
-      AdditionalTypeProviderDelegate delegate) {
+      AdditionalTypeProviderDelegate delegate) throws UnableToCompleteException {
     return buildFrom(logger, resources, delegate, false);
   }
 
+  /**
+   * Compiles the given source files and adds them to the CompilationState.
+   * See {@link CompileMoreLater#compile} for details.
+   * @throws UnableToCompleteException if the compiler aborts (not a normal compile error).
+   */
   public static CompilationState buildFrom(TreeLogger logger, Set<Resource> resources,
-      AdditionalTypeProviderDelegate delegate, boolean suppressErrors) {
+      AdditionalTypeProviderDelegate delegate, boolean suppressErrors)
+      throws UnableToCompleteException {
     Event event = SpeedTracerLogger.start(DevModeEventType.CSB_BUILD_FROM_ORACLE);
     try {
       return instance.doBuildFrom(logger, resources, delegate, suppressErrors);
@@ -416,7 +451,8 @@
    * TODO: maybe use a finer brush than to synchronize the whole thing.
    */
   public synchronized CompilationState doBuildFrom(TreeLogger logger, Set<Resource> resources,
-      AdditionalTypeProviderDelegate compilerDelegate, boolean suppressErrors) {
+      AdditionalTypeProviderDelegate compilerDelegate, boolean suppressErrors)
+    throws UnableToCompleteException {
 
     // Units we definitely want to build.
     List<CompilationUnitBuilder> builders = new ArrayList<CompilationUnitBuilder>();
@@ -467,7 +503,7 @@
   }
 
   public CompilationState doBuildFrom(TreeLogger logger, Set<Resource> resources,
-      boolean suppressErrors) {
+      boolean suppressErrors) throws UnableToCompleteException {
     return doBuildFrom(logger, resources, null, suppressErrors);
   }
 
@@ -478,7 +514,7 @@
    */
   synchronized Collection<CompilationUnit> doBuildGeneratedTypes(TreeLogger logger,
       Collection<GeneratedUnit> generatedUnits, CompileMoreLater compileMoreLater,
-      boolean suppressErrors) {
+      boolean suppressErrors) throws UnableToCompleteException {
 
     // Units we definitely want to build.
     List<CompilationUnitBuilder> builders = new ArrayList<CompilationUnitBuilder>();
diff --git a/dev/core/src/com/google/gwt/dev/javac/JdtCompiler.java b/dev/core/src/com/google/gwt/dev/javac/JdtCompiler.java
index 2494824..92bc20e 100644
--- a/dev/core/src/com/google/gwt/dev/javac/JdtCompiler.java
+++ b/dev/core/src/com/google/gwt/dev/javac/JdtCompiler.java
@@ -15,6 +15,8 @@
  */
 package com.google.gwt.dev.javac;
 
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
 import com.google.gwt.dev.jdt.TypeRefVisitor;
 import com.google.gwt.dev.jjs.InternalCompilerException;
 import com.google.gwt.dev.jjs.ast.JDeclaredType;
@@ -60,6 +62,7 @@
 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
 import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
 import org.eclipse.jdt.internal.compiler.lookup.UnresolvedReferenceBinding;
+import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
 import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
 
 import java.io.IOException;
@@ -230,6 +233,19 @@
               Locale.getDefault()));
     }
 
+    /**
+     * Make the JDT compiler throw the exception so that it can be caught in {@link #doCompile}.
+     */
+    @Override
+    protected void handleInternalException(AbortCompilation abortException,
+        CompilationUnitDeclaration unit) {
+      // Context: The JDT compiler doesn't rethrow AbortCompilation in Compiler.compile().
+      // Instead it just exits early with a random selection of compilation units never getting
+      // compiled. This makes sense when an Eclipse user hits cancel, but in GWT, it will result
+      // in confusing errors later if we don't catch and handle it.
+      throw abortException;
+    }
+
     @Override
     public void process(CompilationUnitDeclaration cud, int i) {
       super.process(cud, i);
@@ -379,15 +395,18 @@
 
   /**
    * Compiles the given set of units. The units will be internally modified to
-   * reflect the results of compilation.
+   * reflect the results of compilation. If the compiler aborts, logs an error
+   * and throws UnableToCompleteException.
    */
-  public static List<CompilationUnit> compile(Collection<CompilationUnitBuilder> builders) {
+  public static List<CompilationUnit> compile(TreeLogger logger,
+      Collection<CompilationUnitBuilder> builders)
+      throws UnableToCompleteException {
     Event jdtCompilerEvent = SpeedTracerLogger.start(CompilerEventType.JDT_COMPILER);
 
     try {
       DefaultUnitProcessor processor = new DefaultUnitProcessor();
       JdtCompiler compiler = new JdtCompiler(processor);
-      compiler.doCompile(builders);
+      compiler.doCompile(logger, builders);
       return processor.getResults();
     } finally {
       jdtCompilerEvent.end();
@@ -704,20 +723,34 @@
     return result;
   }
 
-  public boolean doCompile(Collection<CompilationUnitBuilder> builders) {
+  /**
+   * Compiles source using the JDT. The {@link UnitProcessor#process} callback method will be called
+   * once for each compiled file. If the compiler aborts, logs a message and throws
+   * UnableToCompleteException.
+   */
+  public void doCompile(TreeLogger logger, Collection<CompilationUnitBuilder> builders)
+      throws UnableToCompleteException {
+    if (builders.isEmpty()) {
+      return;
+    }
     List<ICompilationUnit> icus = new ArrayList<ICompilationUnit>();
     for (CompilationUnitBuilder builder : builders) {
       addPackages(Shared.getPackageName(builder.getTypeName()).replace('.', '/'));
       icus.add(new Adapter(builder));
     }
-    if (icus.isEmpty()) {
-      return false;
-    }
 
     compilerImpl = new CompilerImpl();
-    compilerImpl.compile(icus.toArray(new ICompilationUnit[icus.size()]));
-    compilerImpl = null;
-    return true;
+    try {
+      compilerImpl.compile(icus.toArray(new ICompilationUnit[icus.size()]));
+    } catch (AbortCompilation e) {
+      String filename = new String(e.problem.getOriginatingFileName());
+      TreeLogger branch = logger.branch(TreeLogger.Type.ERROR,
+          "At " + filename + ": " + e.problem.getSourceLineNumber());
+      branch.log(TreeLogger.Type.ERROR, "JDT compiler aborted: " + e.problem.getMessage());
+      throw new UnableToCompleteException();
+    } finally {
+      compilerImpl = null;
+    }
   }
 
   public ReferenceBinding resolveType(String typeName) {
diff --git a/dev/core/src/com/google/gwt/dev/javac/StandardGeneratorContext.java b/dev/core/src/com/google/gwt/dev/javac/StandardGeneratorContext.java
index 5dde0d5..f1ab783 100644
--- a/dev/core/src/com/google/gwt/dev/javac/StandardGeneratorContext.java
+++ b/dev/core/src/com/google/gwt/dev/javac/StandardGeneratorContext.java
@@ -456,10 +456,13 @@
    * Call this whenever generators are known to not be running to clear out
    * uncommitted compilation units and to force committed compilation units to
    * be parsed and added to the type oracle.
-   * 
+   *
    * @return any newly generated artifacts since the last call
+   *
+   * @throw UnableToCompleteException if the compiler aborted (not
+   * a normal compile error).</p>
    */
-  public final ArtifactSet finish(TreeLogger logger) {
+  public final ArtifactSet finish(TreeLogger logger) throws UnableToCompleteException {
     abortUncommittedResources(logger);
 
     try {
diff --git a/dev/core/src/com/google/gwt/dev/javac/testing/GeneratorContextBuilder.java b/dev/core/src/com/google/gwt/dev/javac/testing/GeneratorContextBuilder.java
index 5201480..2aa2dc6 100644
--- a/dev/core/src/com/google/gwt/dev/javac/testing/GeneratorContextBuilder.java
+++ b/dev/core/src/com/google/gwt/dev/javac/testing/GeneratorContextBuilder.java
@@ -17,6 +17,7 @@
 
 import com.google.gwt.core.ext.GeneratorContext;
 import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
 import com.google.gwt.dev.javac.CompilationState;
 import com.google.gwt.dev.javac.CompilationStateBuilder;
 import com.google.gwt.dev.javac.StandardGeneratorContext;
@@ -84,7 +85,12 @@
   public GeneratorContext buildGeneratorContext() {
     // TODO: Add ability to add property values later and add them to this
     // context.
-    return new StandardGeneratorContext(buildCompilationState(), null, null, null, false);
+    try {
+      return new StandardGeneratorContext(buildCompilationState(), null, null, null, false);
+    } catch (UnableToCompleteException e) {
+      // TODO: change signature and fix callers (looks like it's just tests)
+      throw new RuntimeException(e);
+    }
   }
 
   /**
@@ -96,9 +102,9 @@
     this.treeLogger = treeLogger;
   }
 
-  private CompilationState buildCompilationState() {
+  private CompilationState buildCompilationState() throws UnableToCompleteException {
     TreeLogger logger = treeLogger != null ? treeLogger : createLogger();
-    return new CompilationStateBuilder().doBuildFrom(logger, resources, null, false);
+      return new CompilationStateBuilder().doBuildFrom(logger, resources, null, false);
   }
 
   private TreeLogger createLogger() {
diff --git a/dev/core/test/com/google/gwt/dev/javac/CompilationStateTestBase.java b/dev/core/test/com/google/gwt/dev/javac/CompilationStateTestBase.java
index e8034bd..8d74ce9 100644
--- a/dev/core/test/com/google/gwt/dev/javac/CompilationStateTestBase.java
+++ b/dev/core/test/com/google/gwt/dev/javac/CompilationStateTestBase.java
@@ -16,6 +16,7 @@
 package com.google.gwt.dev.javac;
 
 import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
 import com.google.gwt.dev.javac.testing.impl.JavaResourceBase;
 import com.google.gwt.dev.javac.testing.impl.MockResource;
 import com.google.gwt.dev.javac.testing.impl.MockResourceOracle;
@@ -102,20 +103,30 @@
    */
   protected final CompilationStateBuilder isolatedBuilder = new CompilationStateBuilder();
 
-  protected MockResourceOracle oracle = new MockResourceOracle(
-      JavaResourceBase.getStandardResources());
+  protected MockResourceOracle oracle;
 
-  protected CompilationState state = isolatedBuilder.doBuildFrom(
-      createTreeLogger(), oracle.getResources(), false);
+  protected CompilationState state;
+
+  protected CompilationStateTestBase() {
+    oracle = new MockResourceOracle(JavaResourceBase.getStandardResources());
+    rebuildCompilationState();
+  }
 
   protected void addGeneratedUnits(MockResource... sourceFiles) {
-    state.addGeneratedCompilationUnits(createTreeLogger(),
-        getGeneratedUnits(sourceFiles));
+    try {
+      state.addGeneratedCompilationUnits(createTreeLogger(),
+          getGeneratedUnits(sourceFiles));
+    } catch (UnableToCompleteException e) {
+      throw new RuntimeException(e);
+    }
   }
 
   protected void rebuildCompilationState() {
-    state = isolatedBuilder.doBuildFrom(createTreeLogger(),
-        oracle.getResources(), false);
+    try {
+      state = isolatedBuilder.doBuildFrom(createTreeLogger(), oracle.getResources(), false);
+    } catch (UnableToCompleteException e) {
+      throw new RuntimeException(e);
+    }
   }
 
   protected void validateCompilationState(String... generatedTypeNames) {
diff --git a/dev/core/test/com/google/gwt/dev/javac/JdtCompilerTest.java b/dev/core/test/com/google/gwt/dev/javac/JdtCompilerTest.java
index 4c12d5c..8a018a2 100644
--- a/dev/core/test/com/google/gwt/dev/javac/JdtCompilerTest.java
+++ b/dev/core/test/com/google/gwt/dev/javac/JdtCompilerTest.java
@@ -15,7 +15,7 @@
  */
 package com.google.gwt.dev.javac;
 
-import com.google.gwt.dev.javac.CompilationUnitBuilder.ResourceCompilationUnitBuilder;
+import com.google.gwt.core.ext.TreeLogger;
 import com.google.gwt.dev.javac.testing.impl.JavaResourceBase;
 import com.google.gwt.dev.resource.Resource;
 
@@ -42,30 +42,30 @@
     }
   }
 
-  public void testCompile() {
+  public void testCompile() throws Exception {
     List<CompilationUnitBuilder> builders = new ArrayList<CompilationUnitBuilder>();
     addAll(builders, JavaResourceBase.getStandardResources());
     addAll(builders, JavaResourceBase.FOO, JavaResourceBase.BAR);
-    Collection<CompilationUnit> units = JdtCompiler.compile(builders);
+    Collection<CompilationUnit> units = JdtCompiler.compile(TreeLogger.NULL, builders);
     assertUnitsCompiled(units);
   }
 
-  public void testCompileError() {
+  public void testCompileError() throws Exception {
     List<CompilationUnitBuilder> builders = new ArrayList<CompilationUnitBuilder>();
     addAll(builders, JavaResourceBase.getStandardResources());
     addAll(builders, JavaResourceBase.BAR);
-    List<CompilationUnit> units = JdtCompiler.compile(builders);
+    List<CompilationUnit> units = JdtCompiler.compile(TreeLogger.NULL, builders);
     assertUnitsCompiled(units.subList(0, units.size() - 1));
     assertUnitHasErrors(units.get(units.size() - 1), 1);
   }
 
-  public void testCompileIncremental() {
+  public void testCompileIncremental() throws Exception {
     List<CompilationUnitBuilder> builders = new ArrayList<CompilationUnitBuilder>();
     addAll(builders, JavaResourceBase.getStandardResources());
-    Collection<CompilationUnit> units = JdtCompiler.compile(builders);
+    Collection<CompilationUnit> units = JdtCompiler.compile(TreeLogger.NULL, builders);
     assertUnitsCompiled(units);
     addAll(builders, JavaResourceBase.FOO, JavaResourceBase.BAR);
-    JdtCompiler.compile(builders);
+    JdtCompiler.compile(TreeLogger.NULL, builders);
     assertUnitsCompiled(units);
   }
 
diff --git a/dev/core/test/com/google/gwt/dev/javac/TypeOracleTestingUtils.java b/dev/core/test/com/google/gwt/dev/javac/TypeOracleTestingUtils.java
index a846741..40f4fa0 100644
--- a/dev/core/test/com/google/gwt/dev/javac/TypeOracleTestingUtils.java
+++ b/dev/core/test/com/google/gwt/dev/javac/TypeOracleTestingUtils.java
@@ -16,6 +16,7 @@
 package com.google.gwt.dev.javac;
 
 import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.UnableToCompleteException;
 import com.google.gwt.core.ext.typeinfo.TypeOracle;
 import com.google.gwt.dev.javac.testing.impl.JavaResourceBase;
 import com.google.gwt.dev.resource.Resource;
@@ -33,9 +34,13 @@
 
   public static CompilationState buildCompilationState(TreeLogger logger, Set<Resource> resources,
       Set<GeneratedUnit> generatedUnits) {
-    CompilationState state = CompilationStateBuilder.buildFrom(logger, resources);
-    state.addGeneratedCompilationUnits(logger, generatedUnits);
-    return state;
+    try {
+      CompilationState state = CompilationStateBuilder.buildFrom(logger, resources);
+      state.addGeneratedCompilationUnits(logger, generatedUnits);
+      return state;
+    } catch (UnableToCompleteException e) {
+      throw new RuntimeException(e);
+    }
   }
 
   public static CompilationState buildStandardCompilationStateWith(TreeLogger logger,
@@ -91,10 +96,13 @@
 
   public static TypeOracle buildTypeOracle(TreeLogger logger,
       Set<Resource> resources, Set<GeneratedUnit> generatedUnits) {
-    CompilationState state = CompilationStateBuilder.buildFrom(logger,
-        resources);
-    state.addGeneratedCompilationUnits(logger, generatedUnits);
-    return state.getTypeOracle();
+    try {
+      CompilationState state = CompilationStateBuilder.buildFrom(logger, resources);
+      state.addGeneratedCompilationUnits(logger, generatedUnits);
+      return state.getTypeOracle();
+    } catch (UnableToCompleteException e) {
+      throw new RuntimeException(e);
+    }
   }
 
   /**
diff --git a/dev/core/test/com/google/gwt/dev/shell/StandardGeneratorContextTest.java b/dev/core/test/com/google/gwt/dev/shell/StandardGeneratorContextTest.java
index 1ce8d39..0f6fd5c 100644
--- a/dev/core/test/com/google/gwt/dev/shell/StandardGeneratorContextTest.java
+++ b/dev/core/test/com/google/gwt/dev/shell/StandardGeneratorContextTest.java
@@ -81,8 +81,7 @@
 
   private final ArtifactSet artifactSet = new ArtifactSet();
   private final StandardGeneratorContext genCtx;
-  private final CompilationState mockCompilationState = CompilationStateBuilder.buildFrom(
-      TreeLogger.NULL, Collections.<Resource> emptySet());
+  private final CompilationState mockCompilationState;
   private final TreeLogger mockLogger = TreeLogger.NULL;
   private final PropertyOracle mockPropOracle = new MockPropertyOracle();
   /**
@@ -92,6 +91,12 @@
   private final List<File> toDelete = new ArrayList<File>();
 
   public StandardGeneratorContextTest() {
+    try {
+      mockCompilationState =
+          CompilationStateBuilder.buildFrom(TreeLogger.NULL, Collections.<Resource>emptySet());
+    } catch (UnableToCompleteException e) {
+      throw new RuntimeException(e);
+    }
     genCtx = new StandardGeneratorContext(mockCompilationState,
         new MockModuleDef(), null, artifactSet, false);
     genCtx.setPropertyOracle(mockPropOracle);
@@ -140,8 +145,7 @@
   /**
    * Tests that calling commit a second time on the same OutputStream throws an
    * exception. Note that this behavior should follow the same basic code path
-   * attempting to commit an unknown OutputStream, as in
-   * {@link #testTryCreateResource_commitWithUnknownStream()}.
+   * attempting to commit an unknown OutputStream.
    */
   public void testTryCreateResource_commitCalledTwice()
       throws UnableToCompleteException, IOException {
diff --git a/tools/api-checker/src/com/google/gwt/tools/apichecker/ApiContainer.java b/tools/api-checker/src/com/google/gwt/tools/apichecker/ApiContainer.java
index 057c5e5..3e72821 100644
--- a/tools/api-checker/src/com/google/gwt/tools/apichecker/ApiContainer.java
+++ b/tools/api-checker/src/com/google/gwt/tools/apichecker/ApiContainer.java
@@ -184,7 +184,7 @@
       CompilationUnitBuilder builder = CompilationUnitBuilder.create(resource);
       builders.add(builder);
     }
-    List<CompilationUnit> units = JdtCompiler.compile(builders);
+    List<CompilationUnit> units = JdtCompiler.compile(logger, builders);
     boolean anyError = false;
     TreeLogger branch = logger.branch(TreeLogger.TRACE, "Checking for compile errors");
     for (CompilationUnit unit : units) {
diff --git a/user/test/com/google/gwt/place/rebind/PlaceHistoryGeneratorContextTest.java b/user/test/com/google/gwt/place/rebind/PlaceHistoryGeneratorContextTest.java
index 37a8c72..dc5c5cc 100644
--- a/user/test/com/google/gwt/place/rebind/PlaceHistoryGeneratorContextTest.java
+++ b/user/test/com/google/gwt/place/rebind/PlaceHistoryGeneratorContextTest.java
@@ -91,7 +91,11 @@
     rtn.add(new RealJavaResource(Tokenizer3.class));
     rtn.add(new RealJavaResource(Tokenizer4.class));
     rtn.addAll(Arrays.asList(resources));
-    return CompilationStateBuilder.buildFrom(createCompileLogger(), rtn).getTypeOracle();
+    try {
+        return CompilationStateBuilder.buildFrom(createCompileLogger(), rtn).getTypeOracle();
+    } catch (UnableToCompleteException e) {
+        throw new RuntimeException(e);
+    }
   }
 
   public void testCreateNotAnInterface() throws UnableToCompleteException {
diff --git a/user/test/com/google/gwt/resources/ext/ResourceGeneratorUtilTest.java b/user/test/com/google/gwt/resources/ext/ResourceGeneratorUtilTest.java
index 3da8a0a..851f121 100644
--- a/user/test/com/google/gwt/resources/ext/ResourceGeneratorUtilTest.java
+++ b/user/test/com/google/gwt/resources/ext/ResourceGeneratorUtilTest.java
@@ -48,7 +48,7 @@
   JMethod voidMethod;
 
   @Override
-  public void setUp() {
+  public void setUp() throws Exception {
     PrintWriterTreeLogger logger = new PrintWriterTreeLogger(new PrintWriter(
         System.err));
     logger.setMaxDetail(TreeLogger.ERROR);
diff --git a/user/test/com/google/gwt/uibinder/rebind/TypeOracleUtilsTest.java b/user/test/com/google/gwt/uibinder/rebind/TypeOracleUtilsTest.java
index 4d26ef0..07084c0 100644
--- a/user/test/com/google/gwt/uibinder/rebind/TypeOracleUtilsTest.java
+++ b/user/test/com/google/gwt/uibinder/rebind/TypeOracleUtilsTest.java
@@ -22,7 +22,6 @@
 import com.google.gwt.core.ext.typeinfo.JClassType;
 import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
 import com.google.gwt.core.ext.typeinfo.JType;
-import com.google.gwt.core.ext.typeinfo.NotFoundException;
 import com.google.gwt.core.ext.typeinfo.TypeOracle;
 import com.google.gwt.dev.javac.CompilationState;
 import com.google.gwt.dev.javac.CompilationStateBuilder;
@@ -214,7 +213,7 @@
   }
 
   @Override
-  protected void setUp() throws NotFoundException {
+  protected void setUp() throws Exception {
     Set<Resource> resources = new HashSet<Resource>();
     resources.addAll(Arrays.asList(JavaResourceBase.getStandardResources()));
     resources.add(FOO);
diff --git a/user/test/com/google/web/bindery/requestfactory/gwt/rebind/model/RequestFactoryModelTest.java b/user/test/com/google/web/bindery/requestfactory/gwt/rebind/model/RequestFactoryModelTest.java
index 2690c7e..6b00159 100644
--- a/user/test/com/google/web/bindery/requestfactory/gwt/rebind/model/RequestFactoryModelTest.java
+++ b/user/test/com/google/web/bindery/requestfactory/gwt/rebind/model/RequestFactoryModelTest.java
@@ -208,8 +208,12 @@
       }
     });
 
-    CompilationState state = CompilationStateBuilder.buildFrom(logger,
-        javaResources);
+    CompilationState state;
+    try {
+        state = CompilationStateBuilder.buildFrom(logger, javaResources);
+    } catch (UnableToCompleteException e) {
+        throw new RuntimeException(e);
+    }
 
     UnitTestTreeLogger.Builder builder = new UnitTestTreeLogger.Builder();
     builder.setLowestLogLevel(TreeLogger.ERROR);