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

He-Pin pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/pekko.git


The following commit(s) were added to refs/heads/main by this push:
     new 6c29b3c4fe Deprecate org.apache.pekko.dispatch.Futures (#3377)
6c29b3c4fe is described below

commit 6c29b3c4fe4f47628f6c7bb6206d5c2f8e021ee5
Author: He-Pin(kerr) <[email protected]>
AuthorDate: Sat Jul 25 21:32:38 2026 +0800

    Deprecate org.apache.pekko.dispatch.Futures (#3377)
    
    * Deprecate org.apache.pekko.dispatch.Futures
    
    Motivation:
    Java users should not need to touch Scala Future at all. Standard
    java.util.concurrent.CompletableFuture and CompletionStages provide
    equivalent functionality.
    
    Modification:
    - Mark Futures object and all its methods as deprecated (since 2.0.0)
    - Add CompletionStages.fromScala as replacement for Futures.asJava
    - Replace internal Futures.failedCompletionStage usage in
      CompletionStages.reduce with CompletableFuture.failedFuture
    - Migrate Java tests to use CompletableFuture/CompletionStages directly
    
    Result:
    Clear deprecation path for Java users toward standard Java APIs.
    
    Tests:
    - sbt "actor-tests/Test/testOnly org.apache.pekko.dispatch.JavaFutureTests 
org.apache.pekko.dispatch.CompletionStagesTests 
org.apache.pekko.pattern.PatternsTest" / 44 passed
    
    References:
    Fixes #1417
    
    * Use CompletableFuture.failedStage instead of failedFuture
    
    Motivation:
    failedStage returns CompletionStage directly, which is the correct
    replacement for failedCompletionStage and matches the return types
    in CompletionStages.reduce and the test callables.
    
    Modification:
    - Fix deprecation message on failedCompletionStage
    - Use failedStage in CompletionStages.reduce
    - Use failedStage in Java test replacements
    
    Result:
    Consistent use of the CompletionStage-typed API.
    
    Tests:
    - sbt "actor-tests/Test/testOnly org.apache.pekko.dispatch.JavaFutureTests 
org.apache.pekko.dispatch.CompletionStagesTests 
org.apache.pekko.pattern.PatternsTest" / 44 passed
    
    References:
    Fixes #1417
    
    * Point Futures.asJava deprecation to CompletionStages.fromScala
    
    Motivation:
    Users should be directed to the new CompletionStages.fromScala method
    rather than the low-level scala.jdk.FutureConverters.
    
    Modification:
    Update deprecation message on Futures.asJava.
    
    Result:
    Consistent migration path through CompletionStages API.
    
    Tests:
    - Not run - message-only change
    
    References:
    Fixes #1417
    
    * Address review: use scala.jdk.javaapi.FutureConverters directly
    
    Motivation:
    Reviewers (raboof, pjfanning) suggested pointing users to the standard
    scala.jdk.javaapi.FutureConverters instead of adding a Pekko-specific
    CompletionStages.fromScala wrapper.
    
    Modification:
    - Remove CompletionStages.fromScala (not needed)
    - Deprecate CompletionStages.asScala pointing to 
scala.jdk.javaapi.FutureConverters.asScala
    - Update Futures.asJava deprecation to point to 
scala.jdk.javaapi.FutureConverters.asJava
    - Update tests to use scala.jdk.javaapi.FutureConverters directly
    
    Result:
    Users are guided to the standard Scala JDK converters which are
    zero-cost thin wrappers (JIT-inlined), avoiding unnecessary Pekko
    indirection while maintaining best performance.
    
    Tests:
    - sbt "actor-tests / Test / testOnly 
org.apache.pekko.dispatch.JavaFutureTests 
org.apache.pekko.dispatch.CompletionStagesTests 
org.apache.pekko.pattern.PatternsTest" — 44 passed
    
    References:
    Refs #1417
---
 .../java/org/apache/pekko/dispatch/CompletionStagesTests.java  |  4 ++--
 .../test/java/org/apache/pekko/dispatch/JavaFutureTests.java   |  8 ++++----
 .../src/test/java/org/apache/pekko/pattern/PatternsTest.java   |  9 +++------
 .../scala/org/apache/pekko/dispatch/CompletionStages.scala     |  8 ++++----
 actor/src/main/scala/org/apache/pekko/dispatch/Future.scala    | 10 +++++++++-
 5 files changed, 22 insertions(+), 17 deletions(-)

diff --git 
a/actor-tests/src/test/java/org/apache/pekko/dispatch/CompletionStagesTests.java
 
b/actor-tests/src/test/java/org/apache/pekko/dispatch/CompletionStagesTests.java
index dbdb3c7a62..8eda8661cc 100644
--- 
a/actor-tests/src/test/java/org/apache/pekko/dispatch/CompletionStagesTests.java
+++ 
b/actor-tests/src/test/java/org/apache/pekko/dispatch/CompletionStagesTests.java
@@ -42,8 +42,8 @@ public class CompletionStagesTests {
         assertEquals(42, Await.result(scalaFuture, timeout).intValue());
         //failed
         assertThrows(RuntimeException.class, () -> {
-            final CompletionStage<Integer> failedCs = 
Futures.failedCompletionStage(new RuntimeException(
-                "Simulated failure"));
+            final CompletionStage<Integer> failedCs = 
CompletableFuture.failedStage(
+                new RuntimeException("Simulated failure"));
             Await.result(CompletionStages.asScala(failedCs), timeout);
         });
     }
diff --git 
a/actor-tests/src/test/java/org/apache/pekko/dispatch/JavaFutureTests.java 
b/actor-tests/src/test/java/org/apache/pekko/dispatch/JavaFutureTests.java
index 0f80bcc953..4bbaf510ea 100644
--- a/actor-tests/src/test/java/org/apache/pekko/dispatch/JavaFutureTests.java
+++ b/actor-tests/src/test/java/org/apache/pekko/dispatch/JavaFutureTests.java
@@ -42,14 +42,14 @@ public class JavaFutureTests {
 
   @Test
   public void mustBeAbleToCreateAJavaCompletionStage() throws Exception {
-    Future<Integer> f = Futures.successful(42);
-    CompletableFuture<Integer> cs = Futures.asJava(f).toCompletableFuture();
+    Future<Integer> f = scala.concurrent.Future$.MODULE$.successful(42);
+    CompletableFuture<Integer> cs = 
scala.jdk.javaapi.FutureConverters.asJava(f).toCompletableFuture();
     assertEquals(42, cs.get(3, TimeUnit.SECONDS).intValue());
   }
 
   @Test
   public void blockMustBeCallable() throws Exception {
-    Promise<String> p = Futures.promise();
+    Promise<String> p = scala.concurrent.Promise$.MODULE$.apply();
     Duration d = Duration.create(1, TimeUnit.SECONDS);
     p.success("foo");
     Await.ready(p.future(), d);
@@ -58,7 +58,7 @@ public class JavaFutureTests {
 
   @Test
   public void mapToMustBeCallable() throws Exception {
-    Promise<Object> p = Futures.promise();
+    Promise<Object> p = scala.concurrent.Promise$.MODULE$.apply();
     Future<String> f = p.future().mapTo(classTag(String.class));
     Duration d = Duration.create(1, TimeUnit.SECONDS);
     p.success("foo");
diff --git 
a/actor-tests/src/test/java/org/apache/pekko/pattern/PatternsTest.java 
b/actor-tests/src/test/java/org/apache/pekko/pattern/PatternsTest.java
index c57f4c9b90..258f83bfca 100644
--- a/actor-tests/src/test/java/org/apache/pekko/pattern/PatternsTest.java
+++ b/actor-tests/src/test/java/org/apache/pekko/pattern/PatternsTest.java
@@ -26,7 +26,6 @@ import java.util.concurrent.*;
 import java.util.concurrent.atomic.AtomicInteger;
 import org.apache.pekko.actor.*;
 import org.apache.pekko.dispatch.CompletionStages;
-import org.apache.pekko.dispatch.Futures;
 import org.apache.pekko.testkit.PekkoJUnitJupiterActorSystemResource;
 import org.apache.pekko.testkit.PekkoSpec;
 import org.apache.pekko.testkit.TestProbe;
@@ -316,7 +315,7 @@ public class PatternsTest {
 
     Future<String> retriedFuture =
         Patterns.retry(
-            () -> Futures.successful(expected),
+            () -> scala.concurrent.Future$.MODULE$.successful(expected),
             3,
             scala.concurrent.duration.Duration.apply(200, "millis"),
             system.scheduler(),
@@ -340,10 +339,9 @@ public class PatternsTest {
   }
 
   @Test
-  @SuppressWarnings("deprecation")
   public void testAfterFailedCallable() throws Exception {
     Callable<CompletionStage<String>> failedCallable =
-        () -> Futures.failedCompletionStage(new 
IllegalStateException("Illegal!"));
+        () -> CompletableFuture.failedStage(new 
IllegalStateException("Illegal!"));
 
     CompletionStage<String> delayedFuture =
         Patterns.after(Duration.ofMillis(200), system.scheduler(), ec, 
failedCallable);
@@ -363,7 +361,6 @@ public class PatternsTest {
   }
 
   @Test
-  @SuppressWarnings("deprecation")
   public void testAfterFailedFuture() throws Exception {
 
     CompletionStage<String> delayedFuture =
@@ -371,7 +368,7 @@ public class PatternsTest {
             Duration.ofMillis(200),
             system.scheduler(),
             ec,
-            () -> Futures.failedCompletionStage(new 
IllegalStateException("Illegal!")));
+            () -> CompletableFuture.failedStage(new 
IllegalStateException("Illegal!")));
 
     CompletionStage<String> resultFuture =
         CompletionStages.firstCompletedOf(List.of(delayedFuture));
diff --git 
a/actor/src/main/scala/org/apache/pekko/dispatch/CompletionStages.scala 
b/actor/src/main/scala/org/apache/pekko/dispatch/CompletionStages.scala
index 808f83016f..01714ecd62 100644
--- a/actor/src/main/scala/org/apache/pekko/dispatch/CompletionStages.scala
+++ b/actor/src/main/scala/org/apache/pekko/dispatch/CompletionStages.scala
@@ -22,8 +22,6 @@ import java.util.concurrent.{ CompletableFuture, 
CompletionStage, Executor }
 import java.util.concurrent.atomic.AtomicReference
 import java.util.function.{ BiConsumer, BiFunction }
 
-import scala.annotation.nowarn
-
 import org.apache.pekko
 
 /**
@@ -33,7 +31,10 @@ object CompletionStages {
 
   /**
    * Convert a `CompletionStage` to a Scala `Future`.
+   *
+   * @deprecated Use `scala.jdk.javaapi.FutureConverters.asScala` instead.
    */
+  @deprecated("Use scala.jdk.javaapi.FutureConverters.asScala instead.", since 
= "2.0.0")
   def asScala[T](stage: CompletionStage[T]): scala.concurrent.Future[T] = {
     import scala.jdk.FutureConverters._
     stage.asScala
@@ -143,7 +144,6 @@ object CompletionStages {
    *         or a `NoSuchElementException` if the given iterable is empty
    * @since 1.2.0
    */
-  @nowarn("msg=deprecated")
   def reduce[T <: AnyRef, R >: T](
       stages: java.lang.Iterable[? <: CompletionStage[? <: T]],
       function: pekko.japi.function.Function2[R, T, R]): CompletionStage[R] = {
@@ -151,7 +151,7 @@ object CompletionStages {
     if (iterator.hasNext) {
       iterator.next().thenCompose { v => foldWithNext[T, R](iterator, v, 
function) }
     } else {
-      Futures.failedCompletionStage(new NoSuchElementException("reduce of an 
empty iterable of CompletionStages"))
+      CompletableFuture.failedStage(new NoSuchElementException("reduce of an 
empty iterable of CompletionStages"))
     }
   }
 
diff --git a/actor/src/main/scala/org/apache/pekko/dispatch/Future.scala 
b/actor/src/main/scala/org/apache/pekko/dispatch/Future.scala
index 3cdab634e3..eaadf96de9 100644
--- a/actor/src/main/scala/org/apache/pekko/dispatch/Future.scala
+++ b/actor/src/main/scala/org/apache/pekko/dispatch/Future.scala
@@ -79,7 +79,10 @@ object ExecutionContexts {
 
 /**
  * Futures is the Java API for Futures and Promises
+ *
+ * @deprecated Use `CompletionStages` and standard 
`java.util.concurrent.CompletableFuture` APIs instead.
  */
+@deprecated("Use CompletionStages and standard 
java.util.concurrent.CompletableFuture APIs instead.", since = "2.0.0")
 object Futures {
 
   /**
@@ -87,6 +90,7 @@ object Futures {
    *
    * @since 1.2.0
    */
+  @deprecated("Use scala.jdk.javaapi.FutureConverters.asJava instead.", since 
= "2.0.0")
   def asJava[T](future: Future[T]): CompletionStage[T] = {
     import scala.jdk.FutureConverters._
     future.asJava
@@ -101,6 +105,7 @@ object Futures {
    * @param executor the execution context on which the future is run
    * @return         the `Future` holding the result of the computation
    */
+  @deprecated("Use CompletableFuture.supplyAsync instead.", since = "2.0.0")
   def future[T](body: Callable[T], executor: ExecutionContext): Future[T] = 
Future(body.call)(executor)
 
   /**
@@ -108,22 +113,25 @@ object Futures {
    *
    * @return         the newly created `Promise` object
    */
+  @deprecated("Use new CompletableFuture instead.", since = "2.0.0")
   def promise[T](): Promise[T] = Promise[T]()
 
   /**
    * creates an already completed Promise with the specified exception
    */
+  @deprecated("Use CompletableFuture.failedFuture instead.", since = "2.0.0")
   def failed[T](exception: Throwable): Future[T] = Future.failed(exception)
 
   /**
    * Creates an already completed Promise with the specified result
    */
+  @deprecated("Use CompletableFuture.completedFuture instead.", since = 
"2.0.0")
   def successful[T](result: T): Future[T] = Future.successful(result)
 
   /**
    * Creates an already completed CompletionStage with the specified exception
    */
-  @deprecated("Use `CompletableFuture#failedStage` instead.", since = "2.0.0")
+  @deprecated("Use CompletableFuture.failedStage instead.", since = "2.0.0")
   def failedCompletionStage[T](ex: Throwable): CompletionStage[T] = {
     val f = CompletableFuture.completedFuture[T](null.asInstanceOf[T])
     f.obtrudeException(ex)


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to