Подтвердить что ты не робот

Преобразование scala будущего в будущее java

У меня есть сгенерированный интерфейс Java, содержащий метод:

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

Я хочу реализовать это с помощью Akka. Я написал следующее:

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

Проблема в том, что ask возвращает scala.concurrent.Future[Any] а метод должен возвращать 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]))
                  ^

Как я могу сделать это преобразование?

4b9b3361

Ответ 1

Ну его нецелесообразно преобразовывать, потому что scala Future не предоставляют функциональности для прерывания или любого другого механизма отмены. Таким образом, нет прямого полнофункционального способа отменить будущее через прерывание или иначе посредством вызова метода в будущем.

Таким образом, самым простым решением может быть, если отмена не требуется:

  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
    }
  }

Но если вам все еще нужно cancel, исправление для инвалидов будет таким, как показано

здесь. Но я бы не рекомендовал его, хотя его шаткий

Ответ 2

Начиная с Scala 2.13, стандартная библиотека включает scala.jdk.FutureConverters который обеспечивает преобразования Scala в Java Future (и наоборот):

import scala.jdk.FutureConverters._

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

Примечание для пользователей Java, вы бы предпочли использовать FutureConverters явным образом:

import scala.jdk.javaapi.FutureConverters;

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

Ответ 3

Я не думаю, что есть простой способ конвертировать scala Future в java Future. Одно из возможных решений заключается в переносе будущего будущего scala на будущее java, но вы должны передать новую задачу в пул потоков, см. Java docs: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html