This is an automated email from the ASF dual-hosted git repository.

daim pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 20e64a2a32 OAK-12132 : remove toCompletableFuture from FutureConverter 
(#2788)
20e64a2a32 is described below

commit 20e64a2a32d3b48ec04a45603f6de06009ee0a43
Author: Rishabh Kumar <[email protected]>
AuthorDate: Fri Mar 6 20:10:33 2026 +0530

    OAK-12132 : remove toCompletableFuture from FutureConverter (#2788)
---
 .../internal/concurrent/FutureConverter.java       |  86 +---------
 .../commons/internal/concurrent/package-info.java  |   2 +-
 .../internal/concurrent/FutureConverterTest.java   | 189 ---------------------
 3 files changed, 3 insertions(+), 274 deletions(-)

diff --git 
a/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/internal/concurrent/FutureConverter.java
 
b/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/internal/concurrent/FutureConverter.java
index 9f9bab4ac7..a97bb39dfb 100644
--- 
a/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/internal/concurrent/FutureConverter.java
+++ 
b/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/internal/concurrent/FutureConverter.java
@@ -21,16 +21,15 @@ package 
org.apache.jackrabbit.oak.commons.internal.concurrent;
 import org.apache.jackrabbit.guava.common.util.concurrent.ListenableFuture;
 import org.jetbrains.annotations.NotNull;
 
-import java.util.List;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executor;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
-import java.util.stream.Collectors;
 
 /**
- * Utility to convert {@link 
org.apache.jackrabbit.guava.common.util.concurrent.ListenableFuture} to {@link 
java.util.concurrent.CompletableFuture}
+ * Utility to convert between {@link 
org.apache.jackrabbit.guava.common.util.concurrent.ListenableFuture}
+ * and {@link java.util.concurrent.CompletableFuture}.
  */
 // TODO: remove this class once we remove all Guava Concurent Packages
 public class FutureConverter {
@@ -38,71 +37,6 @@ public class FutureConverter {
         // no instances for you
     }
 
-    private static final Executor DIRECT_EXECUTOR = Runnable::run;
-
-
-    public static <T> List<CompletableFuture<T>> toCompletableFuture(final 
List<? extends ListenableFuture<T>> listenableFutures) {
-        return listenableFutures.stream()
-                .map(FutureConverter::toCompletableFuture)
-                .collect(Collectors.toList());
-    }
-
-    /**
-     * Converts a {@link 
org.apache.jackrabbit.guava.common.util.concurrent.ListenableFuture}
-     * to a {@link java.util.concurrent.CompletableFuture}.
-     * <p>
-     * The returned CompletableFuture will be completed when the 
ListenableFuture completes,
-     * either with its result or with an exception if the ListenableFuture 
fails.
-     *
-     * @param listenableFuture the ListenableFuture to convert
-     * @param <T> the result type
-     * @return a CompletableFuture representing the same computation
-     */
-    public static <T> CompletableFuture<T> toCompletableFuture(final 
ListenableFuture<T> listenableFuture) {
-        CompletableFuture<T> completable = new CompletableFuture<>() {
-            @Override
-            public boolean cancel(boolean mayInterruptIfRunning) {
-                // Cancel the Guava ListenableFuture
-                boolean canceled = 
listenableFuture.cancel(mayInterruptIfRunning);
-                // Also cancel this CompletableFuture
-                super.cancel(mayInterruptIfRunning);
-                return canceled;
-            }
-
-            @Override
-            public T get() throws InterruptedException, ExecutionException {
-                try {
-                    return super.get();
-                } catch (InterruptedException e) {
-                    // Ensure interrupt status is preserved
-                    Thread.currentThread().interrupt();
-                    throw e;
-                }
-            }
-
-            @Override
-            public T get(long timeout, TimeUnit unit) throws 
InterruptedException, ExecutionException, TimeoutException {
-                try {
-                    return super.get(timeout, unit);
-                } catch (InterruptedException e) {
-                    // Ensure interrupt status is preserved
-                    Thread.currentThread().interrupt();
-                    throw e;
-                }
-            }
-        };
-
-        // Check if the ListenableFuture is already done to avoid unnecessary 
async overhead
-        if (listenableFuture.isDone()) {
-            handleConversion(listenableFuture, completable);
-        } else {
-            // Future is not done yet, add listener for completion
-            listenableFuture.addListener(() -> 
handleConversion(listenableFuture, completable), DIRECT_EXECUTOR);
-        }
-
-        return completable;
-    }
-
     /**
      * Converts a Java {@link CompletableFuture} to a Guava {@link 
ListenableFuture}.
      * <p>
@@ -160,20 +94,4 @@ public class FutureConverter {
         };
     }
 
-    // helper methods
-
-    private static <T> void handleConversion(final ListenableFuture<T> 
listenableFuture, final CompletableFuture<T> completable) {
-        try {
-            if (listenableFuture.isCancelled()) {
-                completable.cancel(false);
-            } else {
-                completable.complete(listenableFuture.get());
-            }
-        } catch (InterruptedException ex) {
-            Thread.currentThread().interrupt();
-            completable.completeExceptionally(ex);
-        } catch (Exception ex) {
-            completable.completeExceptionally(ex.getCause() != null ? 
ex.getCause() : ex);
-        }
-    }
 }
diff --git 
a/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/internal/concurrent/package-info.java
 
b/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/internal/concurrent/package-info.java
index 75cc10fd69..64007c2781 100644
--- 
a/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/internal/concurrent/package-info.java
+++ 
b/oak-commons/src/main/java/org/apache/jackrabbit/oak/commons/internal/concurrent/package-info.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-@Version("1.3.0")
+@Version("2.0.0")
 @Internal(since = "1.0.0")
 package org.apache.jackrabbit.oak.commons.internal.concurrent;
 
diff --git 
a/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/internal/concurrent/FutureConverterTest.java
 
b/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/internal/concurrent/FutureConverterTest.java
index f638b95b7d..9f3c131685 100644
--- 
a/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/internal/concurrent/FutureConverterTest.java
+++ 
b/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/internal/concurrent/FutureConverterTest.java
@@ -19,12 +19,9 @@
 package org.apache.jackrabbit.oak.commons.internal.concurrent;
 
 import org.apache.jackrabbit.guava.common.util.concurrent.ListenableFuture;
-import org.apache.jackrabbit.guava.common.util.concurrent.SettableFuture;
 import org.junit.Assert;
 import org.junit.Test;
 
-import java.util.Arrays;
-import java.util.List;
 import java.util.concurrent.CancellationException;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CountDownLatch;
@@ -37,192 +34,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
  */
 public class FutureConverterTest {
 
-    @Test
-    public void testSuccessfulCompletion() throws Exception {
-        SettableFuture<String> listenable = SettableFuture.create();
-        CompletableFuture<String> completable = 
FutureConverter.toCompletableFuture(listenable);
-
-        listenable.set("success");
-
-        // Should complete with the same value
-        Assert.assertEquals("success", completable.get(1, TimeUnit.SECONDS));
-        Assert.assertTrue(completable.isDone());
-        Assert.assertFalse(completable.isCompletedExceptionally());
-    }
-
-    @Test
-    public void testExceptionalCompletion() {
-        SettableFuture<String> listenable = SettableFuture.create();
-        CompletableFuture<String> completable = 
FutureConverter.toCompletableFuture(listenable);
-
-        listenable.setException(new RuntimeException("fail!"));
-
-        // Should complete exceptionally
-        ExecutionException ex = Assert.assertThrows(ExecutionException.class, 
() -> completable.get(1, TimeUnit.SECONDS));
-        Assert.assertTrue(ex.getCause() instanceof RuntimeException);
-        Assert.assertEquals("fail!", ex.getCause().getMessage());
-        Assert.assertTrue(completable.isCompletedExceptionally());
-    }
-
-    @Test
-    public void testCancellation() {
-        SettableFuture<String> listenable = SettableFuture.create();
-        CompletableFuture<String> completable = 
FutureConverter.toCompletableFuture(listenable);
-
-        listenable.cancel(true);
-
-        // Should complete exceptionally with CancellationException
-        Assert.assertThrows(CancellationException.class, () -> 
completable.get(1, TimeUnit.SECONDS));
-        Assert.assertTrue(completable.isCompletedExceptionally());
-    }
-
-    @Test
-    public void toCompletableFutureCancelFromListenable() {
-        SettableFuture<String> listenable = SettableFuture.create();
-        CompletableFuture<String> completable = 
FutureConverter.toCompletableFuture(listenable);
-
-        listenable.cancel(true);
-
-        try {
-            completable.get(1, TimeUnit.SECONDS);
-            Assert.fail("Expected CancellationException");
-        } catch (CancellationException e) {
-            // expected
-        } catch (Exception e) {
-            Assert.fail("Unexpected exception: " + e);
-        }
-
-        Assert.assertTrue(completable.isCancelled());
-    }
-
-    @Test
-    public void toCompletableFutureCancelFromCompletable() {
-        SettableFuture<String> listenable = SettableFuture.create();
-        CompletableFuture<String> completable = 
FutureConverter.toCompletableFuture(listenable);
-
-        boolean cancelled = completable.cancel(true);
-
-        Assert.assertTrue(cancelled);
-        Assert.assertTrue(completable.isCancelled());
-        Assert.assertTrue(listenable.isCancelled());
-    }
-
-    @Test
-    public void toCompletableFutureTestGetRestoresInterruptStatus() throws 
Exception {
-        SettableFuture<String> listenable = SettableFuture.create();
-        CompletableFuture<String> completable = 
FutureConverter.toCompletableFuture(listenable);
-
-        final AtomicBoolean interruptedInCatch = new AtomicBoolean(false);
-        final AtomicBoolean caughtInterruptedException = new 
AtomicBoolean(false);
-        final CountDownLatch threadStarted = new CountDownLatch(1);
-
-        Thread testThread = new Thread(() -> {
-            threadStarted.countDown();
-            try {
-                completable.get(); // This will block, we interrupt
-                Assert.fail("Expected InterruptedException");
-            } catch (InterruptedException e) {
-                // Expected interrupt
-                caughtInterruptedException.set(true);
-                interruptedInCatch.set(Thread.currentThread().isInterrupted());
-            } catch (Exception e) {
-                Assert.fail("Unexpected exception: " + e);
-            }
-        });
-
-        testThread.start();
-        // Wait for thread to start and then interrupt
-        threadStarted.await();
-        Thread.sleep(50); // Small delay to ensure get() is called
-        testThread.interrupt();
-
-        testThread.join();
-
-        Assert.assertTrue("Should have caught InterruptedException", 
caughtInterruptedException.get());
-        Assert.assertTrue("Thread should be interrupted when catching 
InterruptedException", interruptedInCatch.get());
-    }
-
-    @Test
-    public void toCompletableFutureTestGetTimeoutRestoresInterruptStatus() 
throws Exception {
-        SettableFuture<String> listenable = SettableFuture.create();
-        CompletableFuture<String> completable = 
FutureConverter.toCompletableFuture(listenable);
-
-        final AtomicBoolean interruptedInCatch = new AtomicBoolean(false);
-        final AtomicBoolean caughtInterruptedException = new 
AtomicBoolean(false);
-        final CountDownLatch threadStarted = new CountDownLatch(1);
-
-        Thread testThread = new Thread(() -> {
-            threadStarted.countDown();
-            try {
-                completable.get(10, TimeUnit.SECONDS); // Will block and get 
interrupted
-                Assert.fail("Expected InterruptedException");
-            } catch (InterruptedException e) {
-                // Expected interrupt
-                caughtInterruptedException.set(true);
-                interruptedInCatch.set(Thread.currentThread().isInterrupted());
-            } catch (Exception e) {
-                Assert.fail("Unexpected exception: " + e);
-            }
-        });
-
-        testThread.start();
-        // Wait for thread to start and then interrupt
-        threadStarted.await();
-        Thread.sleep(50); // Small delay to ensure get() is called
-        testThread.interrupt();
-
-        testThread.join();
-
-        Assert.assertTrue("Should have caught InterruptedException", 
caughtInterruptedException.get());
-        Assert.assertTrue("Thread should be interrupted when catching 
InterruptedException", interruptedInCatch.get());
-    }
-
-    @Test
-    public void testConvertListSuccessful() throws Exception {
-        SettableFuture<String> f1 = SettableFuture.create();
-        SettableFuture<String> f2 = SettableFuture.create();
-
-        List<ListenableFuture<String>> listenableList = Arrays.asList(f1, f2);
-        List<CompletableFuture<String>> completableList = 
FutureConverter.toCompletableFuture(listenableList);
-
-        // Complete Guava futures
-        f1.set("first");
-        f2.set("second");
-
-        // Assert CompletableFuture results
-        Assert.assertEquals("first", completableList.get(0).get());
-        Assert.assertEquals("second", completableList.get(1).get());
-    }
-
-    @Test
-    public void testConvertListPartialFailure() {
-        SettableFuture<String> f1 = SettableFuture.create();
-        SettableFuture<String> f2 = SettableFuture.create();
-
-        List<ListenableFuture<String>> listenableList = Arrays.asList(f1, f2);
-        List<CompletableFuture<String>> completableList = 
FutureConverter.toCompletableFuture(listenableList);
-
-        f1.set("ok");
-        f2.setException(new RuntimeException("fail"));
-
-        // Verify first future succeeds
-        try {
-            Assert.assertEquals("ok", completableList.get(0).get());
-        } catch (Exception e) {
-            Assert.fail("First future should succeed");
-        }
-
-        // Verify second future completes exceptionally
-        Assert.assertThrows(ExecutionException.class, () -> 
completableList.get(1).get());
-    }
-
-    @Test
-    public void testConvertListEmpty() {
-        List<ListenableFuture<String>> emptyList = List.of();
-        List<CompletableFuture<String>> completableList = 
FutureConverter.toCompletableFuture(emptyList);
-        Assert.assertTrue(completableList.isEmpty());
-    }
-
     @Test
     public void toListenableFutureSuccessfulCompletion() throws Exception {
         CompletableFuture<String> completable = new CompletableFuture<>();

Reply via email to