我在 Java 中使用 Classic Akka 时遇到问题。看来 Akka 在创建 actor 和使用 .tell() 时无法使用 Java 的内置类型转换。
下面是我的代码的简化版本:
主要课程:
import akka.actor.ActorSystem;
import akka.actor.ActorRef;
import akka.actor.Props;
import java.util.UUID;
public class Main {
public static void main(String[] args){
ActorSystem system = ActorSystem.create("system");
ActorRef actorA = system.actorOf(Props.create(ActorA.class , 0), UUID.randomUUID().toString());
actorA.tell(new ActorA.MessageA(7,3),ActorRef.noSender());
}
}
演员:
import akka.actor.UntypedAbstractActor;
public class ActorA extends UntypedAbstractActor {
private long result;
public ActorA(long StartValue) {
}
//on method: MessageA
public static final class MessageA {
public final double paramD;
public final long paramL;
public MessageA(double paramD, long paramL) {
this.paramD = paramD;
this.paramL = paramL;
}
}
private void onMessageA(double paramD,long paramL) {
System.out.println(paramD);
System.out.println(paramL);
}
public void onReceive(Object message) {
if (message instanceof MessageA MessageAMsg) {
onMessageA(MessageAMsg.paramD, MessageAMsg.paramL);
} else {
unhandled(message);
}
}
}
但是,当我运行此代码时,遇到以下错误:
Exception in thread "main" java.lang.IllegalArgumentException: no matching constructor found on class output.ActorA for arguments [class java.lang.Integer]
...
在创建 ActorA 实例时,Akka 似乎期望一个 Integer 参数而不是 long。双精度数和整数也是如此。我很困惑,因为 Java 通常隐式处理类型转换。 Akka 这样做有什么具体原因吗?我该如何解决这个问题?
任何见解或建议将不胜感激。谢谢!
使用
Props.create
(如 Props.create(ActorA.class , 0)
中所示)需要反思性地构造 actor,这意味着正常的 Java 类型升级并不是“免费”的。作为特殊情况,此类促销必须由Props.create
手动实施。
由于反射形式不是推荐的做法,因此不太可能添加该特殊情况(尽管我怀疑实现该特殊情况的 PR 很可能会被接受;请注意,虽然我受雇于 Lightbend,但我是 无法做出任何形式的预测是否会发生这种接受)。
如果使用
Props.create(ActorA.class, () -> new ActorA(0))
,则适用通常的 Java 促销。由于 main
是 static
,因此关于该方法无意中关闭状态的警告不适用,但为了解决这个问题,可以这样做:
public class ActorA extends UntypedAbstractActor {
public static Props props(long startValue) {
return Props.create(ActorA.class, () -> new ActorA(startValue));
}
}