/ /エラースカラを使用してhttpサーバの非常に基本的なテストを行っている間akkaスプレーcan - scala、akka、httpserver、スプレー

scala akka spray can - scala、akka、httpserver、sprayを使用してhttpサーバの非常に基本的なテストを行っているときにエラーが発生しました

私はスプレー缶の非常に基本的なテストを行った:

  • Akka 2.10 2.24
  • Scala 2.10.3
  • スプレー缶1.3.1
  • sbt 0.13
  • IntelliJ 13

ここに私のコードです:

val myListener: ActorRef = system.actorOf(Props[TestHttpListener], "httpListener")
IO(Http) ! Http.Bind(myListener, interface = "localhost", port = 8080)

httpListener 反応する Http.Connected 〜と Http.Register(self).

私は自分のコードを実行するためにsbtを使用します。それは AbstractMethodError

[ERROR] [07/12/2014 18:46:48.364] [default-akka.actor.default-dispatcher-5] [ActorSystem(default)] Uncaught error from thread [default-akka.actor.default-dispatcher-5] shutting down JVM since "akka.jvm-exit-on-fatal-error" is enabled
java.lang.AbstractMethodError: spray.can.HttpManager.akka$actor$ActorLogging$_setter_$log_$eq(Lakka/event/LoggingAdapter;)V
at akka.actor.ActorLogging$class.$init$(Actor.scala:335)
at spray.can.HttpManager.<init>(HttpManager.scala:29)
at spray.can.HttpExt$$anonfun$1.apply(Http.scala:153)
at spray.can.HttpExt$$anonfun$1.apply(Http.scala:153)
at akka.actor.TypedCreatorFunctionConsumer.produce(Props.scala:422)
at akka.actor.Props.newActor(Props.scala:331)
at akka.actor.ActorCell.newActor(ActorCell.scala:534)
at akka.actor.ActorCell.create(ActorCell.scala:560)
at akka.actor.dungeon.FaultHandling$class.finishCreate(FaultHandling.scala:135)
at akka.actor.dungeon.FaultHandling$class.faultCreate(FaultHandling.scala:129)
at akka.actor.ActorCell.faultCreate(ActorCell.scala:338)
at akka.actor.dungeon.FaultHandling$class.faultRecreate(FaultHandling.scala:58)
at akka.actor.ActorCell.faultRecreate(ActorCell.scala:338)
at akka.actor.ActorCell.invokeAll$1(ActorCell.scala:428)
at akka.actor.ActorCell.systemInvoke(ActorCell.scala:447)
at akka.dispatch.Mailbox.processAllSystemMessages(Mailbox.scala:262)
at akka.dispatch.Mailbox.run(Mailbox.scala:218)
at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:385)
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)

回答:

回答№1は5

Scalaの世界では、すべてのバージョンが急速に発展し、主要バージョン間の後方互換性が保証されていないので、バージョンに注意することは非常に重要です。

スプレー 依存する アッカ そして このページ サポートされる組み合わせに関する情報が含まれています。

スプレー1.3.1は、Scala 2.10.3およびAkka 2.3.0ならびにScala 2.11.1およびAkka 2.3.2に対して作成されています。

したがって、Scala 2.10.3を使用する場合、Akkaの正しいバージョンは少なくとも2.3.0になります。

また、あなたが次のように思っている例 この ページはあまり良くありません。

まず第一に、あなたがコードを初期化するコード IO(Http) ! Http.Bind(...) 俳優の中にいる必要があります。受け取った俳優 Http.Bind 返信しようとする Http.Bound 呼び出し元が俳優ではないので、あなたは死んだ手紙を受け取ります。

だから、私はこのようなことをすることをお勧めします:

class MyApp extends Actor {

implicit val system = context.system

override def receive: Receive = {
case "start" =>
val myListener: ActorRef = system.actorOf(Props[TestHttpListener], "httpListener")
IO(Http) ! Http.Bind(myListener, interface = "localhost", port = 8080)
}
}

それから、 main() あなたのアプリの必要なメソッド:

val myApp: ActorRef = system.actorOf(Props[MyApp], "myApp")
myApp ! "start"

この例から理解しにくいもう一つのことは、リスナーのアクターでは、メッセージを処理するだけでなく、すべての接続で自身を登録する必要があることです。

class TestHttpListener extends Actor {
def receive = {
case HttpRequest(HttpMethods.GET, Uri.Path("/ping"), _, _, _) =>
sender() ! HttpResponse(entity = "PONG")

case c : Tcp.Connected =>
sender() ! Http.Register(self)
}
}