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 8dcd69c4edacb27b710ebaf526e75c0de100fc84 Author: Guillaume Nodet <[email protected]> AuthorDate: Sun Jun 7 09:43:21 2026 +0000 Fix SmartExecutor — add RejectedExecutionException fallback to Callable overloads Pooled.submit(Callable) and Limited.submit(Callable) did not catch RejectedExecutionException, unlike their Runnable counterparts. On rejection, Pooled would let the REE propagate with a never-completed future, and Limited would additionally leak a semaphore permit. Apply the same try-catch-fallback pattern: on rejection, run the callable on the caller thread and complete the future inline. --- .../aether/util/concurrency/SmartExecutor.java | 42 +++++++++++++++------- 1 file changed, 30 insertions(+), 12 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 fcae4f911..3b2f25c1f 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 @@ -110,17 +110,25 @@ public interface SmartExecutor extends AutoCloseable { public <T> Future<T> submit(Callable<T> callable) { ClassLoader tccl = Thread.currentThread().getContextClassLoader(); CompletableFuture<T> future = new CompletableFuture<>(); - executor.submit(() -> { - ClassLoader old = Thread.currentThread().getContextClassLoader(); - Thread.currentThread().setContextClassLoader(tccl); + try { + executor.submit(() -> { + ClassLoader old = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(tccl); + try { + future.complete(callable.call()); + } catch (Exception e) { + future.completeExceptionally(e); + } finally { + Thread.currentThread().setContextClassLoader(old); + } + }); + } catch (RejectedExecutionException e) { try { future.complete(callable.call()); - } catch (Exception e) { - future.completeExceptionally(e); - } finally { - Thread.currentThread().setContextClassLoader(old); + } catch (Exception ex) { + future.completeExceptionally(ex); } - }); + } return future; } @@ -176,15 +184,25 @@ public interface SmartExecutor extends AutoCloseable { try { semaphore.acquire(); CompletableFuture<T> future = new CompletableFuture<>(); - executor.submit(() -> { + try { + executor.submit(() -> { + try { + future.complete(callable.call()); + } catch (Exception e) { + future.completeExceptionally(e); + } finally { + semaphore.release(); + } + }); + } catch (RejectedExecutionException e) { try { future.complete(callable.call()); - } catch (Exception e) { - future.completeExceptionally(e); + } catch (Exception ex) { + future.completeExceptionally(ex); } finally { semaphore.release(); } - }); + } return future; } catch (InterruptedException e) { Thread.currentThread().interrupt();
