diff --git a/src/main/java/org/codeaholics/tools/build/pant/DependencyGraphEntry.java b/src/main/java/org/codeaholics/tools/build/pant/DependencyGraphEntry.java index fd3b5c4..4720765 100644 --- a/src/main/java/org/codeaholics/tools/build/pant/DependencyGraphEntry.java +++ b/src/main/java/org/codeaholics/tools/build/pant/DependencyGraphEntry.java @@ -19,6 +19,7 @@ import java.util.HashSet; import java.util.Set; +import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Target; public class DependencyGraphEntry implements Runnable { @@ -87,6 +88,8 @@ public void run() { executionNotifier.notifyStarting(this); try { targetExecutor.executeTarget(target); + } catch (BuildException e) { + executionNotifier.notifyException(this, e); } finally { executionNotifier.notifyComplete(this); } diff --git a/src/main/java/org/codeaholics/tools/build/pant/ParallelExecutor.java b/src/main/java/org/codeaholics/tools/build/pant/ParallelExecutor.java index e826f6e..081f405 100644 --- a/src/main/java/org/codeaholics/tools/build/pant/ParallelExecutor.java +++ b/src/main/java/org/codeaholics/tools/build/pant/ParallelExecutor.java @@ -45,6 +45,8 @@ public class ParallelExecutor implements Executor { private AntWrapper antWrapper = new AntWrapperImpl(); private ExecutorService executorService; + private final List buildExceptions = new LinkedList(); + private int queued; @SuppressWarnings("unused") private int started; @@ -112,6 +114,25 @@ private void executeTarget(final Target target, final Map target } catch (final InterruptedException e) { // ignore } + + // Check for any exceptions that were thrown from the executorService + if (buildExceptions.size() > 1) { + // Combine the multiple exceptions into a new BuildException so all the errors are propagated to the user + String msg = "\n" + buildExceptions.size() + " failures occurred while building:"; + + int i = 0; + for (BuildException e : buildExceptions) { + i += 1; + msg += "\nFailure " + i + ":\n" + e + "\n"; + } + + throw new BuildException(msg); + } else { + // 0 or 1 exceptions, if 1 exists then just throw it + for (BuildException e : buildExceptions) { + throw e; + } + } } private int getNumberOfThreads(final Project project) { @@ -171,6 +192,12 @@ public synchronized void notifyComplete(final DependencyGraphEntry dependencyGra executorService.shutdown(); } } + + @Override + public synchronized void notifyException(final DependencyGraphEntry dependencyGraphEntry, BuildException e) { + buildExceptions.add(e); + executorService.shutdown(); + } }; } @@ -235,4 +262,4 @@ private void verifyPrePhaseTargets(final Map targetsByName) { public Executor getSubProjectExecutor() { return SUB_EXECUTOR; } -} \ No newline at end of file +} diff --git a/src/main/java/org/codeaholics/tools/build/pant/TargetExecutionNotifier.java b/src/main/java/org/codeaholics/tools/build/pant/TargetExecutionNotifier.java index 117a40f..d0b326f 100644 --- a/src/main/java/org/codeaholics/tools/build/pant/TargetExecutionNotifier.java +++ b/src/main/java/org/codeaholics/tools/build/pant/TargetExecutionNotifier.java @@ -16,7 +16,10 @@ * limitations under the License. */ +import org.apache.tools.ant.BuildException; + public interface TargetExecutionNotifier { public void notifyStarting(DependencyGraphEntry dependencyGraphEntry); public void notifyComplete(DependencyGraphEntry dependencyGraphEntry); + public void notifyException(DependencyGraphEntry dependencyGraphEntry, BuildException e); }