diff --git a/.mvn/extensions.xml b/.mvn/extensions.xml index a2d496cc..43d62816 100644 --- a/.mvn/extensions.xml +++ b/.mvn/extensions.xml @@ -2,6 +2,6 @@ io.jenkins.tools.incrementals git-changelist-maven-extension - 1.0-beta-4 + 1.2 diff --git a/pom.xml b/pom.xml index 2712d2a6..5a9439d9 100644 --- a/pom.xml +++ b/pom.xml @@ -44,9 +44,9 @@ - scm:git:git://github.com/jenkinsci/${project.artifactId}-plugin.git - scm:git:git@github.com:jenkinsci/${project.artifactId}-plugin.git - https://github.com/jenkinsci/${project.artifactId}-plugin + scm:git:git://github.com/${gitHubRepo}.git + scm:git:git@github.com:${gitHubRepo}.git + https://github.com/${gitHubRepo} ${scmTag} @@ -69,6 +69,7 @@ false true 3.0 + jenkinsci/${project.artifactId}-plugin diff --git a/src/main/java/org/jenkinsci/plugins/workflow/support/concurrent/ChainingListenableFuture.java b/src/main/java/org/jenkinsci/plugins/workflow/support/concurrent/ChainingListenableFuture.java index 1232d0fb..932a8c14 100644 --- a/src/main/java/org/jenkinsci/plugins/workflow/support/concurrent/ChainingListenableFuture.java +++ b/src/main/java/org/jenkinsci/plugins/workflow/support/concurrent/ChainingListenableFuture.java @@ -208,7 +208,7 @@ public void run() { ChainingListenableFuture.this.outputFuture = null; } } - }, MoreExecutors.sameThreadExecutor()); + }, Futures.newExecutorService()); } catch (UndeclaredThrowableException e) { // Set the cause of the exception as this future's exception setException(e.getCause()); diff --git a/src/main/java/org/jenkinsci/plugins/workflow/support/concurrent/Futures.java b/src/main/java/org/jenkinsci/plugins/workflow/support/concurrent/Futures.java index 8900e6de..9b313f24 100644 --- a/src/main/java/org/jenkinsci/plugins/workflow/support/concurrent/Futures.java +++ b/src/main/java/org/jenkinsci/plugins/workflow/support/concurrent/Futures.java @@ -26,9 +26,12 @@ import com.google.common.util.concurrent.SettableFuture; import javax.annotation.Nullable; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.util.concurrent.Uninterruptibles.getUninterruptibly; @@ -65,7 +68,7 @@ public abstract class Futures { * });} * *

Note: This overload of {@code addCallback} is designed for cases in - * which the callack is fast and lightweight, as the method does not accept + * which the callback is fast and lightweight, as the method does not accept * an {@code Executor} in which to perform the the work. For heavier * callbacks, this overload carries some caveats: First, the thread that the * callback runs in depends on whether the input {@code Future} is done at the @@ -74,7 +77,7 @@ public abstract class Futures { * callback in the thread that calls {@code addCallback} or {@code * Future.cancel}. Second, callbacks may run in an internal thread of the * system responsible for the input {@code Future}, such as an RPC network - * thread. Finally, during the execution of a {@code sameThreadExecutor} + * thread. Finally, during the execution of a {@code newExecutorService} * callback, all other registered but unexecuted listeners are prevented from * running, even if those listeners are to run in other executors. * @@ -87,7 +90,7 @@ public abstract class Futures { */ public static void addCallback(ListenableFuture future, FutureCallback callback) { - addCallback(future, callback, MoreExecutors.sameThreadExecutor()); + addCallback(future, callback, newExecutorService()); } /** @@ -115,8 +118,8 @@ public static void addCallback(ListenableFuture future, * * When the callback is fast and lightweight consider {@linkplain * Futures#addCallback(ListenableFuture, FutureCallback) the other overload} - * or explicit use of {@link MoreExecutors#sameThreadExecutor - * sameThreadExecutor}. For heavier callbacks, this choice carries some + * or explicit use of {@link #newExecutorService()}. + * For heavier callbacks, this choice carries some * caveats: First, the thread that the callback runs in depends on whether * the input {@code Future} is done at the time {@code addCallback} is called * and on whether the input {@code Future} is ever cancelled. In particular, @@ -124,7 +127,7 @@ public static void addCallback(ListenableFuture future, * {@code addCallback} or {@code Future.cancel}. Second, callbacks may run in * an internal thread of the system responsible for the input {@code Future}, * such as an RPC network thread. Finally, during the execution of a {@code - * sameThreadExecutor} callback, all other registered but unexecuted + * newExecutorService} callback, all other registered but unexecuted * listeners are prevented from running, even if those listeners are to run * in other executors. * @@ -218,7 +221,7 @@ public static ListenableFuture immediateFailedFuture( * thread that called {@code transform}. Second, transformations may run in * an internal thread of the system responsible for the input {@code Future}, * such as an RPC network thread. Finally, during the execution of a {@code - * sameThreadExecutor} transformation, all other registered but unexecuted + * newExecutorService} transformation, all other registered but unexecuted * listeners are prevented from running, even if those listeners are to run * in other executors. * @@ -240,7 +243,7 @@ public static ListenableFuture immediateFailedFuture( */ public static ListenableFuture transform(ListenableFuture future, final Function function) { - return Futures.transform(future, function, MoreExecutors.sameThreadExecutor()); + return Futures.transform(future, function, newExecutorService()); } /** @@ -272,7 +275,7 @@ public static ListenableFuture transform(ListenableFuture future, *

Note: For cases in which the transformation is fast and lightweight, * consider {@linkplain Futures#transform(ListenableFuture, Function) the * other overload} or explicit use of {@link - * MoreExecutors#sameThreadExecutor}. For heavier transformations, this + * #newExecutorService}. For heavier transformations, this * choice carries some caveats: First, the thread that the transformation * runs in depends on whether the input {@code Future} is done at the time * {@code transform} is called. In particular, if called late, {@code @@ -280,7 +283,7 @@ public static ListenableFuture transform(ListenableFuture future, * {@code transform}. Second, transformations may run in an internal thread * of the system responsible for the input {@code Future}, such as an RPC * network thread. Finally, during the execution of a {@code - * sameThreadExecutor} transformation, all other registered but unexecuted + * newExecutorService} transformation, all other registered but unexecuted * listeners are prevented from running, even if those listeners are to run * in other executors. * @@ -304,6 +307,29 @@ public static ListenableFuture transform(ListenableFuture future, return chain(future, wrapperFunction, executor); } + /** + * Returns an {@link ExecutorService} to be used as a parameter in other methods. + * It calls {@code MoreExecutors#newDirectExecutorService} or falls back to {@code MoreExecutors#sameThreadExecutor} + * for compatibility with older (< 18.0) versions of guava. + * + * @since TODO + */ + public static ExecutorService newExecutorService() { + try { + try { + // Guava older than 18 + Method method = MoreExecutors.class.getMethod("sameThreadExecutor"); + return (ExecutorService) method.invoke(null); + } catch (NoSuchMethodException e) { + // TODO invert this to prefer the newer guava method once guava is upgrade in Jenkins core + Method method = MoreExecutors.class.getMethod("newDirectExecutorService"); + return (ExecutorService) method.invoke(null); + } + } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e ) { + throw new RuntimeException(e); + } + } + /** * Creates a new {@code ListenableFuture} whose value is a list containing the * values of all its input futures, if all succeed. If any input fails, the @@ -324,7 +350,7 @@ public static ListenableFuture transform(ListenableFuture future, public static ListenableFuture> allAsList( ListenableFuture... futures) { return new ListFuture(ImmutableList.copyOf(futures), true, - MoreExecutors.sameThreadExecutor()); + newExecutorService()); } /** @@ -347,7 +373,7 @@ public static ListenableFuture> allAsList( public static ListenableFuture> allAsList( Iterable> futures) { return new ListFuture(ImmutableList.copyOf(futures), true, - MoreExecutors.sameThreadExecutor()); + newExecutorService()); } /** @@ -379,14 +405,14 @@ public static ListenableFuture> allAsList( *

Note: For cases in which the work of creating the derived future is * fast and lightweight, consider {@linkplain Futures#chain(ListenableFuture, * Function) the other overload} or explicit use of {@code - * sameThreadExecutor}. For heavier derivations, this choice carries some + * newExecutorService}. For heavier derivations, this choice carries some * caveats: First, the thread that the derivation runs in depends on whether * the input {@code Future} is done at the time {@code chain} is called. In * particular, if called late, {@code chain} will run the derivation in the * thread that called {@code chain}. Second, derivations may run in an * internal thread of the system responsible for the input {@code Future}, * such as an RPC network thread. Finally, during the execution of a {@code - * sameThreadExecutor} {@code chain} function, all other registered but + * newExecutorService} {@code chain} function, all other registered but * unexecuted listeners are prevented from running, even if those listeners * are to run in other executors. * diff --git a/src/main/java/org/jenkinsci/plugins/workflow/support/concurrent/ListFuture.java b/src/main/java/org/jenkinsci/plugins/workflow/support/concurrent/ListFuture.java index 61322fd1..a7c961be 100644 --- a/src/main/java/org/jenkinsci/plugins/workflow/support/concurrent/ListFuture.java +++ b/src/main/java/org/jenkinsci/plugins/workflow/support/concurrent/ListFuture.java @@ -75,7 +75,7 @@ public void run() { // Let go of the memory held by other futures ListFuture.this.futures = null; } - }, MoreExecutors.sameThreadExecutor()); + }, Futures.newExecutorService()); // Now begin the "real" initialization.