1

I am new to Scala and I am building a Scala wrapper for my Java API

I have four Java Interfaces

public interface Client<T> {
 <T> Handle<T> execute(App<T> app);
}

public interface App<T> extends Serializable{
  T process(AppContext context) throws Exception;
}

public interface AppContext {
  File getDirectory();
  void deleteDirectory();
  File createDirectory(String path);
}

public interface Handle<T> extends Future<T> {
   static interface Listener<T> {          
       void onSuccess(Handle<T> handle)
       void onFailure(Handle<T> handle, Throwable e)
   }

   void addListener(Listener<T> listener);
}

Here are my Scala Equivalents

trait Process[T] extends Future[T] { 
  // Few abstract methods
}


class ProcessImpl[T](handle: Handle[T]) extends Process[T] {

val promise = Promise[T]

override def isCompleted: Boolean = ???

override def onComplete[U](func: (Try[T]) => U)(implicit executor: ExecutionContext)  = {
  case Success(t) => promise.success(handle.get())
  case Failure(e) => promise.failure(e)
   }

override def value: Option[Try[T]] = ???

@throws(classOf[Exception])
override def result(atMost: Duration)(implicit permit: CanAwait): T = ???

@throws(classOf[InterruptedException])
@throws(classOf[TimeoutException])
override def ready(atMost: Duration)(implicit permit: CanAwait) = ???

 } 


class ScalaClient(javaClient: Client) {
   def execute[T](func: AppContext => T): ScalaHandle[T] = {
     val app = new App[T]
     @throws(classOf[Exception])
     override def process(AppContext context): T = func(context)

     val handle = javaClient.execute(app) // This returns a Handle obj. I want to convert it to ScalaHandle

    //My approach

     val scalahandle = new ProcessImpl(handle)       
     scalahandle
  }
}

I'm getting the following error

The argument types of an anonymous function must be fully known. (SLS 8.5)

Expected type was: Unit override def onComplete[U](func: (Try[T]) => U)(implicit executor: ExecutionContext) = {

Also, I want to know if my approach here is right

1 Answer 1

4

Your problem isn't in onComplete per se—it's in the way you implement it.

override def onComplete[U](func: (Try[T]) => U)(implicit executor: ExecutionContext)  = {
  case Success(t) => promise.success(test.get())
  case Failure(e) => promise.failure(e)
}

Here, you define onComplete as a partial function from some function Try[_] => U—the type is not known, and it's definitely not overriding the original method, abstract def onComplete[U](f: (Try[T]) ⇒ U)(implicit executor: ExecutionContext): Unit. Note that no case matches anything here: the func is not a Try[T] here.

As a side note, I cannot but mention that you should never ever extend a Future. A very useful motto is, avoid inheritance at any cost. In your case, I don't think inheritance wins you anything—rather, it adds to confusion.

What you probably are looking for is,

def asFuture[T](handle: Handle[T]): Future[T] = {
  val promise = Promise[T]()
  handle.addListener(new Handle.Listener[T] {
    def onSuccess(handle: Handle[T]) {
      promise.trySuccess(handle.get())
    }
    def onFailure(handle: Handle[T], e: Throwable) {
      promise.tryFailure(e)
    }
  })
  promise.future
}
Sign up to request clarification or add additional context in comments.

7 Comments

Sorry for not providing clear information. I have edited my question. I need to have inheritance here to have a non blocking scala future for my API.
You don't need to, you just see it as a reasonable way. I would suggest you to write a function which takes a Handle, registers a listener on it, and when the underlying Handle is complete, completes a Promise. Now the only thing you return here is that Promice's .future—no inheritance, no coupling.
But having it in onComplete would be an ideal Scala API. Though this can be done by adding listeners, I feel it's just not the scala way of doing it
It wouldn't; the onComplete is already provided by a Future, there's no need to implement a new one.
In the above code that you have posted should it be promise.trySuccess(handle.get) ?? Because Handle<T> extends JFuture
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.