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();

Reply via email to