Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert scala future to java future

I have a generated java interface containing a method:

public Future<?> getCustomersAsync(AsyncHandler<Customer> asyncHandler);

I want to implement it using Akka. I wrote following:

override def getCustomerAsync(asyncHandler: AsyncHandler[Customer]): Future[_] = {
  myActorRef.ask(GetCustomer, system.actorOf(Props[Responder]))
}

The issue is that ask returns scala.concurrent.Future[Any] and the method must return java.util.concurrent.Future[?]:

Error:(33, 17) type mismatch;
 found   : scala.concurrent.Future[Any]
 required: java.util.concurrent.Future[?]
    myActorRef.ask(GetCustomer, system.actorOf(Props[Responder]))
                  ^

How can I do this conversion?

like image 595
mirelon Avatar asked Feb 02 '15 12:02

mirelon


People also ask

What is the difference between a Java Future and a Scala Future?

A Java Future works in a synchronous blocking way. It does not work in an asynchronous non-blocking way, whereas a Scala Future works in an asynchronous non-blocking way. If we want an asynchronous non-blocking feature, we should use Java 8's CompletableFuture.

Is Scala the future?

Future represents a result of an asynchronous computation that may or may not be available yet. When we create a new Future, Scala spawns a new thread and executes its code. Once the execution is finished, the result of the computation (value or exception) will be assigned to the Future.

Is Scala Future blocking?

By default, futures and promises are non-blocking, making use of callbacks instead of typical blocking operations. To simplify the use of callbacks both syntactically and conceptually, Scala provides combinators such as flatMap , foreach , and filter used to compose futures in a non-blocking way.

What is Future type in Java?

A Future represents the result of an asynchronous computation. Methods are provided to check if the computation is complete, to wait for its completion, and to retrieve the result of the computation.


2 Answers

Starting Scala 2.13, the standard library includes scala.jdk.FutureConverters which provides Scala to Java Future conversions (and vice versa):

import scala.jdk.FutureConverters._

// val scalaFuture: scala.concurrent.Future[Int] = Future.successful(42)
scalaFuture.asJava
// java.util.concurrent.CompletionStage[Int] = <function1>

Note for Java users, you'd rather use FutureConverters the explicit way:

import scala.jdk.javaapi.FutureConverters;

// val scalaFuture: scala.concurrent.Future[Int] = Future.successful(42)
FutureConverters.asJava(scalaFuture);
// java.util.concurrent.CompletionStage[Int] = <function1>
like image 143
Xavier Guihot Avatar answered Sep 24 '22 10:09

Xavier Guihot


Well its not practical to convert them, because scala Future do not provide functionality to interrupt or any other mechanism for cancellation. So there is no direct full-proof way to cancel a future via interruption or otherwise via method call in Future.

So the simplest solution can be if cancellation is not desired would be:

  def convert[T](x:Future[T]):java.util.concurrent.Future[T]={
    new concurrent.Future[T] {
      override def isCancelled: Boolean = throw new UnsupportedOperationException

      override def get(): T = Await.result(x, Duration.Inf)

      override def get(timeout: Long, unit: TimeUnit): T = Await.result(x, Duration.create(timeout, unit))

      override def cancel(mayInterruptIfRunning: Boolean): Boolean = throw new UnsupportedOperationException

      override def isDone: Boolean = x.isCompleted
    }
  }

But in case if you still need cancel, a handicapped fix would be as shown

here. But I wouldn't recommend it though as its shaky

like image 29
Jatin Avatar answered Sep 22 '22 10:09

Jatin