This is an automated email from the ASF dual-hosted git repository. gnodet pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/maven-resolver.git
commit 9341e597db38d5a91906457ddfb52507c6cb3974 Author: Guillaume Nodet <[email protected]> AuthorDate: Sun Jun 7 06:30:12 2026 +0000 Fix SmartExecutor RejectedExecutionException causing await() hang F-07: When executor.submit() throws RejectedExecutionException, fall back to running the task on the caller thread. This prevents RunnableErrorForwarder.await() from hanging forever when the counter was incremented by wrap() but the task never runs. --- .../aether/util/concurrency/SmartExecutor.java | 39 +++++++++++++++++----- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/maven-resolver-util/src/main/java/org/eclipse/aether/util/concurrency/SmartExecutor.java b/maven-resolver-util/src/main/java/org/eclipse/aether/util/concurrency/SmartExecutor.java index 387a10886..fcae4f911 100644 --- a/maven-resolver-util/src/main/java/org/eclipse/aether/util/concurrency/SmartExecutor.java +++ b/maven-resolver-util/src/main/java/org/eclipse/aether/util/concurrency/SmartExecutor.java @@ -22,6 +22,7 @@ import java.util.concurrent.Callable; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; +import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.Semaphore; /** @@ -84,15 +85,25 @@ public interface SmartExecutor extends AutoCloseable { @Override public void submit(Runnable runnable) { ClassLoader tccl = Thread.currentThread().getContextClassLoader(); - executor.submit(() -> { - ClassLoader old = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(tccl); + try { + executor.submit(() -> { + ClassLoader old = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(tccl); + try { + runnable.run(); + } finally { + Thread.currentThread().setContextClassLoader(old); + } + }); + } catch (RejectedExecutionException e) { try { runnable.run(); - } finally { - Thread.currentThread().setContextClassLoader(old); + } catch (RuntimeException | Error t) { + // swallow to match async submit() semantics where exceptions + // are captured by the Future; callers like RunnableErrorForwarder + // already record the error before re-throwing } - }); + } } @Override @@ -136,13 +147,25 @@ public interface SmartExecutor extends AutoCloseable { public void submit(Runnable runnable) { try { semaphore.acquire(); - executor.submit(() -> { + try { + executor.submit(() -> { + try { + runnable.run(); + } finally { + semaphore.release(); + } + }); + } catch (RejectedExecutionException e) { try { runnable.run(); + } catch (RuntimeException | Error t) { + // swallow to match async submit() semantics where exceptions + // are captured by the Future; callers like RunnableErrorForwarder + // already record the error before re-throwing } finally { semaphore.release(); } - }); + } } catch (InterruptedException e) { Thread.currentThread().interrupt(); }
