将future.onComplete与Java和Akka一起使用,使用不同的Result作为String

Jan*_*Jan 2 java future akka

我有以下问题......

我正在使用Java中的Akka 2.3.6并希望完成以下任务:

Future<Object> future = ask(actor, new GetPOIDataMessage(tenant), Timeout.durationToTimeout(duration));
    future.onSuccess(new OnComplete<NonSimpleObject>() {
                          public void onComplete(Throwable failure, final NonSimpleObject data) {
                              if (failure != null) {
                                  deferredResult.setErrorResult("An error occured during the request");
                              } else {
                                  deferredResult.setResult(data);
                              }
                          }
                      }, ec);
Run Code Online (Sandbox Code Playgroud)

NonSimpleObject是从actor发回的消息的类型.编译我的代码时出现以下错误:

error: method onSuccess in interface Future<T> cannot be applied to given types;
[error]         future.onSuccess(new OnComplete<NonSimpleObject>() {    
[error]               ^
[error]   required: PartialFunction<Object,U>,ExecutionContext
[error]   found: <anonymous OnComplete< NonSimpleObject >>,ExecutionContext
[error]   reason: cannot infer type-variable(s) U
[error]     (argument mismatch; <anonymous OnComplete< NonSimpleObject >> cannot be converted to PartialFunction<Object,U>)
[error]   where U,T are type-variables:
[error]     U extends Object declared in method <U>onSuccess(PartialFunction<T,U>,ExecutionContext)
[error]     T extends Object declared in interface Future`
Run Code Online (Sandbox Code Playgroud)

我无法解码.现在似乎已经过头了.它可以很好地使用String作为结果.我在网上找不到其他使用不同字符串的例子.

感谢您指出正确的方向.一月

cmb*_*ter 5

我认为你的问题源于试图使用一个OnComplete<NonSimpleObject>而不是一个OnComplete<Object>.该Future你是Future<Object>,那么按理说,你只能使用一个OnComplete<Object>.我不认为你可以投,因为那似乎对我不起作用.以下是您尝试执行的操作的简化工作示例:

public class NonSimpleObject{
  public final int i;
  public final String s;

  public NonSimpleObject(String s, int i){
      this.s = s;
      this.i = i;
  }
}

public class SimpleActor extends UntypedActor{
  public SimpleActor(){

  }
  public void onReceive(Object msg){
    getSender().tell(new NonSimpleObject("foo", 11), getContext().self());
  }
}

import scala.concurrent.Future;
import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;
import static akka.pattern.Patterns.ask;
import akka.dispatch.*;

class AskTest{

  public static void main(String[] args) {
    ActorSystem system = ActorSystem.create();
    ActorRef ref = system.actorOf(Props.create(SimpleActor.class));
    Future<Object> fut = ask(ref, "foo", 1000);
    fut.onComplete(new OnComplete<Object>(){
        public void onComplete(Throwable t, Object result){
          System.out.println(((NonSimpleObject)result).s);
        }
    }, system.dispatcher());
  }
}
Run Code Online (Sandbox Code Playgroud)

Java和Scala与Futures之间的互操作性似乎并不那么好.这个例子在纯scala中更容易,在Java中看起来相当笨拙.在Scala中,Future已经mapTo这样你就可以得到正确的类型,你Future,但我没有看到,可以在Java中使用任何模拟.

编辑

在玩了一下之后,我发现了一种非常强硬的方式来使用mapToFuture来获得正确的打字.你可以尝试这样的事情,但就像我说的,这是它如何获得所需的斯卡拉的hackish ClassTagmapTo:

import scala.concurrent.Future;
import scala.reflect.ClassTag$;
import scala.reflect.ClassTag;
import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;
import static akka.pattern.Patterns.ask;
import akka.dispatch.*;

class AskTest{

  public static void main(String[] args) {
    ActorSystem system = ActorSystem.create();
    ActorRef ref = system.actorOf(Props.create(SimpleActor.class));

    ClassTag<NonSimpleObject> tag = ClassTag$.MODULE$.apply(NonSimpleObject.class);
    Future<NonSimpleObject> fut = ask(ref, "foo", 1000).mapTo(tag);
    fut.onComplete(new OnComplete<NonSimpleObject>(){
        public void onComplete(Throwable t, NonSimpleObject result){
          System.out.println(result.s);
        }
    }, system.dispatcher());
  }
}
Run Code Online (Sandbox Code Playgroud)