Question

In this problem I have to call a third-party Java library that expects a java.util.concurrent.Future with a result from a Scala routine returning a scala.concurrent.Future as for example.

def someScalaFunction(): scala.concurrent.Future[T]

def otherJavaMethod(arg: java.util.concurrent.Future[T]) = ...

I would wrap the Scala-Future into a new Java-Future, however there is no way to implement the Java-Future method def cancel(mayInterruptIfRunning: Boolean): Boolean in a way it interrupts the wrapped Scala-Future (if otherwise please let me know).

How can I solve this problem? These are the approaches I come up with:

  1. write the wrapper anyway and just ignore the call on cancel (or throw an NotImplementedError)
  2. change someScalaFunction to maybe return a closure that will then be wrapped by the caller in a Scala or Java Future.

The problem with 1. is that some client could rely on the proper implementation of cancel but is maybe not very critical. 2. would result in a really ugly api.

Was it helpful?

Solution

Note that the cancel only attempts to cancel the task, there are no guarantees according to the Javadoc. So you don't really have to implement it to do something -- depending on what the future computation is, ignoring the cancel call may not be subsequential for the entire application.

If you really need to cancel it, see this question for a half-solution.

Otherwise, you could use your second solution -- with the help of some implicit conversions you could make it look nicer.

object JavaInterOp {
  implicit def f2future[F[_]](f: () => T): java.util.concurrent.Future[T] = fc(f)
}

This way, the import controls which conversion you want to provide and when.

One issue with this is that it might do the conversion where you don't really want it -- it might yield surprising effects.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top