28

I want to change the return type of the method below to Future[Unit]

def send(data: Array[Byte]): CompletableFuture[Void] = {
  val f:CompletableFuture[Void] = client.send(data)
  f
}

I'm using Scala 2.12.1. Is there any convenient way to convert from Java 8 CompletableFuture to Scala's Future?

Sebastian
  • 16,813
  • 4
  • 49
  • 56

3 Answers3

45

Yes, it's called scala-java8-compat, and here's the method you're looking for.

Viktor Klang
  • 26,479
  • 7
  • 51
  • 68
20

Though 2.12 was mentioned by asker (in 2017), now we have 2.13 and the conversion has become easier:

Starting Scala 2.13, the standard library includes scala.jdk.FutureConverters which provides Java to Scala CompletableFuture/Future implicit conversions:

import scala.jdk.FutureConverters._

val scalaFuture = javaFuture.asScala

Convert a Java Future to a Scala Future

akauppi
  • 17,018
  • 15
  • 95
  • 120
1

To convert a CompletableFuture to Scala's Future and get rid of the wrapping CompletionException:

package mycompany.common.concurrent

object Extensions {
  implicit class UnwrappedCompletableFuture[T](cf: CompletableFuture[T]) {

    import scala.jdk.FutureConverters._

    def toScala: Future[T] = {
      val f = cf.asScala
      f.recover {
        case ex: CompletionException if ex.getCause != null => throw ex.getCause
      }(ExecutionContext.global)
    }
  }
}

Usage:

import mycompany.common.concurrent.Extensions._

val result = fetcher.fetchAsync().toScala.recover {
  case ex: YourActualException => 
}
galbarm
  • 2,441
  • 3
  • 32
  • 52