【问题标题】:Akka.io, No matching constructor found on class actorsAkka.io,在类参与者上找不到匹配的构造函数
【发布时间】:2014-09-28 06:08:58
【问题描述】:

我正在尝试设置 Akka 演员来处理网络套接字。

我已经定义了一个简单的actor来通过网络套接字发送消息:

package actors;
import akka.actor.*;

public class MyWebSocketActor extends UntypedActor {

    public static Props props(ActorRef out) {
        return Props.create(MyWebSocketActor.class, out);
    }

    private final ActorRef out;

    public MyWebSocketActor(ActorRef out ) {
        this.out = out;
    }

    public void onReceive(Object message) throws Exception {
        if (message instanceof String) {
            out.tell(message, self());
        }
    }
}

在应用程序控制器中,我有网络套接字:

package controllers;
import play.*;
import play.mvc.*;
import akka.util.*;
import views.html.*;
import actors.MyWebSocketActor;
import play.libs.F.*;

public class Application extends Controller {

    public static Result index() {
        return ok(index.render("Your new application is ready."));
    }

     public static WebSocket<String> socket() {
        return WebSocket.withActor(MyWebSocketActor::props);
     }

}

到目前为止,一切都按我的预期进行。现在,在控制器中,我试图将消息传递给那个演员。我试过了:

public class Messages extends Controller {

    private static final Form<Message> messageForm = Form.form(Message.class);
    @BodyParser.Of(BodyParser.Json.class)

    public static Result list(Integer page) {
        // --- Render
        ActorRef myActor = Akka.system().actorOf(Props.create(MyWebSocketActor.class));
        String message = "test";
        myActor.tell(message, ActorRef.noSender());
        //  
    }

但是出现了错误:“无法调用操作,最终出现错误:java.lang.IllegalArgumentException: no matching constructor found on class actor.MyWebSocketActor for arguments[]。

2014-08-05 05:50:23,503 - [INFO] - from play in pool-4-thread-4 
Listening for HTTP on /0:0:0:0:0:0:0:0:9000

2014-08-05 05:51:02,887 - [ERROR] - from application in New I/O worker #1 


! @6j5b25956 - Internal server error, for (GET) [/] ->

play.PlayExceptions$CompilationException: Compilation error[error: method tell in class ActorRef cannot be applied to given types;]
    at play.PlayExceptions$CompilationException$.apply(PlayExceptions.scala:27) ~[na:na]
    at play.PlayExceptions$CompilationException$.apply(PlayExceptions.scala:27) ~[na:na]
    at scala.Option.map(Option.scala:145) ~[scala-library-2.11.1.jar:na]
    at play.PlayReloader$$anon$1$$anonfun$play$PlayReloader$$anon$$taskFailureHandler$1.apply(PlayReloader.scala:297) ~[na:na]
    at play.PlayReloader$$anon$1$$anonfun$play$PlayReloader$$anon$$taskFailureHandler$1.apply(PlayReloader.scala:292) ~[na:na]
    at scala.Option.map(Option.scala:145) ~[scala-library-2.11.1.jar:na]
    at play.PlayReloader$$anon$1.play$PlayReloader$$anon$$taskFailureHandler(PlayReloader.scala:292) ~[na:na]
    at play.PlayReloader$$anon$1$$anonfun$reload$2.apply(PlayReloader.scala:325) ~[na:na]
    at play.PlayReloader$$anon$1$$anonfun$reload$2.apply(PlayReloader.scala:325) ~[na:na]
    at scala.util.Either$LeftProjection.map(Either.scala:377) ~[scala-library-2.11.1.jar:na]
    at play.PlayReloader$$anon$1.reload(PlayReloader.scala:325) ~[na:na]
    at play.core.ReloadableApplication$$anonfun$get$1.apply(ApplicationProvider.scala:107) ~[play_2.11-2.3.1.jar:2.3.1]
    at play.core.ReloadableApplication$$anonfun$get$1.apply(ApplicationProvider.scala:105) ~[play_2.11-2.3.1.jar:2.3.1]
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24) ~[scala-library-2.11.1.jar:na]
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24) ~[scala-library-2.11.1.jar:na]
    at scala.concurrent.forkjoin.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1361) ~[scala-library-2.11.1.jar:na]
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260) ~[scala-library-2.11.1.jar:na]
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339) ~[scala-library-2.11.1.jar:na]
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979) ~[scala-library-2.11.1.jar:na]
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107) ~[scala-library-2.11.1.jar:na]

2014-08-05 05:51:03,084 - [WARN] - from play in New I/O worker #1 
No application found at invoker init

2014-08-05 06:08:03,586 - [ERROR] - from application in New I/O worker #2 

【问题讨论】:

    标签: java sockets akka playframework-2.3


    【解决方案1】:

    我可以看到的一个问题是,在您的控制器中,您尝试实例化 MyWebSocketActor 的新实例,但您没有为其提供正确的构造函数信息以允许创建该新实例。问题是这里的这一行:

    ActorRef myActor = Akka.system().actorOf(Props.create(MyWebSocketActor.class));
    

    在您的 MyWebSocketActor 中,您没有无参数构造函数。您有一个构造函数定义为:

    public MyWebSocketActor(ActorRef out ) {
        this.out = out;
    }
    

    现在,您可以在 MyWebSocketActor 上的静态 props 方法中正确执行此操作。如果你真的希望能够在你的控制器中实例化这个actor的一个新实例(而不是查找一个现有的实例),你需要有一个ActorRef(在你的构造函数中称为out)来传递. 如果你有,那么你可以修改你的代码如下:

    ActorRef myActor = Akka.system().actorOf(MyWebSocketActor.props(outRef));
    

    编辑

    现在,如果您想查找现有的 Actor,而不是创建每个请求的 Actor,您首先需要确保您想要查找的 Actor 实例已经创建并以您可以查看的方式命名它了。所以是这样的:

    Akka.system().actorOf(MyWebSocketActor.props(outRef), "myactor");
    

    然后,在您的控制器中,您可以使用 ActorSelection 来查找预先存在的演员,如下所示:

    ActorSelection myActorSel = Akka.system().actorSelection("/user/myactor");
    

    ActorSelection 不是ActorRef,也不共享一些基本接口/抽象类。然而,它确实支持tell 操作,就像ActorRef 一样,因此您可以在查找后调用tell。如果你的演员以那个名字存在,那么事情应该会很好。

    您可以在“通过 ActorSelection 识别演员”部分阅读更多关于 ActorSelections here 的信息。

    【讨论】:

    • 说实话(我是 akka.io 的菜鸟)我不知道我可以寻找现有的演员。我认为这是要走的路:) ...你有什么例子可以指出我吗?
    • @Ilproff_77,我更新了我的答案以讨论如何查找现有演员。
    • 如果我理解了您发布的内容,这意味着我不能再使用 WebSocket.withActor,我必须在 Application.java 类中声明该actor。顺便说一句,我是否应该再使用带有 outRef 的构造函数?我不明白这是什么意思。
    • 我只是想告诉你你当前的代码有什么问题。关于在哪里创建演员以及是否需要ActorRef 作为out 回复的决定将取决于您。我还没有深入研究 Play 如何处理 websocket,这超出了我将要提交的答案的范围。
    • 好的@cmbaxter。谢谢!这是我第一个使用 play 和 akka 的项目。我只是有点迷路:)
    【解决方案2】:

    你的actor只有一个带参数的构造函数,out。使用actorOf 创建actor 时,不要传递该参数。这也是错误消息所说的,你的actor没有不带参数的构造函数。

    有趣的是你在你的actor中定义了一个静态的props消息。如果你使用它而不是在 actorOf 中创建 Props,你会得到一个编译器警告 ;-)

    【讨论】:

      猜你喜欢
      • 2017-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-20
      • 2020-01-14
      • 1970-01-01
      • 1970-01-01
      • 2017-07-18
      相关资源
      最近更新 更多