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]