diff --git a/maven-plugin/src/main/java/hudson/maven/AbstractMavenBuilder.java b/maven-plugin/src/main/java/hudson/maven/AbstractMavenBuilder.java index 2281a4ad3189aac867121ff2280b48f8d9688d14..fbd9f3d61ee73c69379533fba7a9932ab49dc5c6 100644 --- a/maven-plugin/src/main/java/hudson/maven/AbstractMavenBuilder.java +++ b/maven-plugin/src/main/java/hudson/maven/AbstractMavenBuilder.java @@ -24,7 +24,7 @@ package hudson.maven; import hudson.model.BuildListener; -import jenkins.model.Jenkins; +import hudson.model.Executor; import hudson.model.Result; import hudson.remoting.Channel; import hudson.remoting.DelegatingCallable; @@ -35,6 +35,10 @@ import java.io.Serializable; import java.text.NumberFormat; import java.util.List; import java.util.Map; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.ExecutionException; + +import jenkins.model.Jenkins; /** * @author Olivier Lamy @@ -61,7 +65,7 @@ public abstract class AbstractMavenBuilder implements DelegatingCallable> futures; + private transient /*final*/ List> futures; protected AbstractMavenBuilder(BuildListener listener, List goals, Map systemProps) { this.listener = listener; @@ -109,10 +113,53 @@ public abstract class AbstractMavenBuilder implements DelegatingCallable>(); + } + + /** + * Records a new asynchronous exection. + */ protected void recordAsynchronousExecution(Future future) { futures.add(future); } + /** + * Waits until all asynchronous executions are finished. + * + * @return null in success case; returns an ABORT result if we were interrupted while waiting + */ + protected Result waitForAsynchronousExecutions() { + try { + boolean messageReported = false; + + for (Future f : futures) { + try { + if(!f.isDone() && !messageReported) { + messageReported = true; + listener.getLogger().println(Messages.MavenBuilder_Waiting()); + } + f.get(); + } catch (InterruptedException e) { + // attempt to cancel all asynchronous tasks + for (Future g : futures) + g.cancel(true); + listener.getLogger().println(Messages.MavenBuilder_Aborted()); + return Executor.currentExecutor().abortResult(); + } catch (ExecutionException e) { + e.printStackTrace(listener.error(Messages.MavenBuilder_AsyncFailed())); + } + } + return null; + } finally { + futures.clear(); + } + } + protected class FilterImpl extends MavenBuildProxy2.Filter implements Serializable { private MavenBuildInformation mavenBuildInformation; diff --git a/maven-plugin/src/main/java/hudson/maven/Maven3Builder.java b/maven-plugin/src/main/java/hudson/maven/Maven3Builder.java index f8483882a475e63d9cd1fd92ddc01c06be81df64..93a34e4ffa9d2c753cb471ff8f852f43d3d24380 100644 --- a/maven-plugin/src/main/java/hudson/maven/Maven3Builder.java +++ b/maven-plugin/src/main/java/hudson/maven/Maven3Builder.java @@ -27,11 +27,9 @@ import hudson.Launcher; import hudson.maven.MavenBuild.ProxyImpl2; import hudson.maven.util.ExecutionEventLogger; import hudson.model.BuildListener; -import hudson.model.Executor; import hudson.model.Result; import hudson.remoting.Channel; import hudson.remoting.DelegatingCallable; -import hudson.remoting.Future; import hudson.util.IOException2; import java.io.IOException; @@ -48,7 +46,6 @@ import java.util.Set; import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.ExecutionException; import java.util.logging.Logger; import org.apache.maven.cli.PrintStreamLogger; @@ -101,7 +98,7 @@ public class Maven3Builder extends AbstractMavenBuilder implements DelegatingCal MavenExecutionListener mavenExecutionListener = new MavenExecutionListener( this ); try { - futures = new CopyOnWriteArrayList>( ); + initializeAsynchronousExecutions(); Maven3Launcher.setMavenExecutionListener( mavenExecutionListener ); @@ -115,27 +112,14 @@ public class Maven3Builder extends AbstractMavenBuilder implements DelegatingCal int r = Maven3Main.launch( goals.toArray(new String[goals.size()])); // now check the completion status of async ops - boolean messageReported = false; long startTime = System.nanoTime(); - for (Future f : futures) { - try { - if(!f.isDone() && !messageReported) { - messageReported = true; - listener.getLogger().println(Messages.MavenBuilder_Waiting()); - } - f.get(); - } catch (InterruptedException e) { - // attempt to cancel all asynchronous tasks - for (Future g : futures) - g.cancel(true); - listener.getLogger().println(Messages.MavenBuilder_Aborted()); - return Executor.currentExecutor().abortResult(); - } catch (ExecutionException e) { - e.printStackTrace(listener.error(Messages.MavenBuilder_AsyncFailed())); - } + + Result waitForAsyncExecutionsResult = waitForAsynchronousExecutions(); + if (waitForAsyncExecutionsResult != null) { + return waitForAsyncExecutionsResult; } + mavenExecutionListener.overheadTime += System.nanoTime()-startTime; - futures.clear(); if(profile) { NumberFormat n = NumberFormat.getInstance(); diff --git a/maven-plugin/src/main/java/hudson/maven/MavenBuild.java b/maven-plugin/src/main/java/hudson/maven/MavenBuild.java index 3dca963030a8687e8f0d29780a2dc5adfa715a13..a189fc0b5391589288a45bf50b21a98c332b61d0 100644 --- a/maven-plugin/src/main/java/hudson/maven/MavenBuild.java +++ b/maven-plugin/src/main/java/hudson/maven/MavenBuild.java @@ -36,7 +36,6 @@ import hudson.model.Computer; import hudson.model.Descriptor; import hudson.model.Environment; import hudson.model.Executor; -import jenkins.model.Jenkins; import hudson.model.Node; import hudson.model.Result; import hudson.model.Run; @@ -319,7 +318,7 @@ public class MavenBuild extends AbstractMavenBuild { @Override public void executeAsync(final BuildCallable program) throws IOException { - futures.add(Channel.current().callAsync(new AsyncInvoker(core,program))); + recordAsynchronousExecution(Channel.current().callAsync(new AsyncInvoker(core,program))); } public MavenBuildInformation getMavenBuildInformation() diff --git a/maven-plugin/src/main/java/hudson/maven/MavenBuilder.java b/maven-plugin/src/main/java/hudson/maven/MavenBuilder.java index 03c907162ebe37f0f5337fe4e287bea29b65e3d3..561b229a4a80999cbcf3522565a79d921d3ca6de 100644 --- a/maven-plugin/src/main/java/hudson/maven/MavenBuilder.java +++ b/maven-plugin/src/main/java/hudson/maven/MavenBuilder.java @@ -29,12 +29,10 @@ import hudson.maven.agent.Main; import hudson.maven.agent.PluginManagerListener; import hudson.maven.reporters.SurefireArchiver; import hudson.model.BuildListener; -import hudson.model.Executor; import hudson.model.Result; import hudson.remoting.Callable; import hudson.remoting.Channel; import hudson.remoting.DelegatingCallable; -import hudson.remoting.Future; import hudson.util.IOException2; import java.io.IOException; @@ -42,11 +40,8 @@ import java.io.PrintStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.text.NumberFormat; -import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.concurrent.ExecutionException; - import org.apache.maven.BuildFailureException; import org.apache.maven.execution.MavenSession; import org.apache.maven.execution.ReactorManager; @@ -137,7 +132,7 @@ public abstract class MavenBuilder extends AbstractMavenBuilder implements Deleg try { - futures = new ArrayList>(); + initializeAsynchronousExecutions(); Adapter a = new Adapter(this); callSetListenerWithReflectOnInterceptors( a, mavenJailProcessClassLoader ); @@ -154,27 +149,14 @@ public abstract class MavenBuilder extends AbstractMavenBuilder implements Deleg int r = Main.launch(goals.toArray(new String[goals.size()])); // now check the completion status of async ops - boolean messageReported = false; long startTime = System.nanoTime(); - for (Future f : futures) { - try { - if(!f.isDone() && !messageReported) { - messageReported = true; - listener.getLogger().println(Messages.MavenBuilder_Waiting()); - } - f.get(); - } catch (InterruptedException e) { - // attempt to cancel all asynchronous tasks - for (Future g : futures) - g.cancel(true); - listener.getLogger().println(Messages.MavenBuilder_Aborted()); - return Executor.currentExecutor().abortResult(); - } catch (ExecutionException e) { - e.printStackTrace(listener.error(Messages.MavenBuilder_AsyncFailed())); - } + + Result waitForAsyncExecutionsResult = waitForAsynchronousExecutions(); + if (waitForAsyncExecutionsResult != null) { + return waitForAsyncExecutionsResult; } + a.overheadTime += System.nanoTime()-startTime; - futures.clear(); if(profile) { NumberFormat n = NumberFormat.getInstance();