Akka:上下文变成抛出 NullPointerException?

Akka: context become throws NullPointerException?

我有一个非常简单的演员定义为:

object CoreActor extends Actor with ActorLogging {
  //  val SYSTEM_NAME = "CoreActors"
  val system = Akka.system()
  //  val system = ActorSystem.create("push", ConfigFactory.load.getConfig("push"))
  val pushUri = Play.current.configuration.getString("pushservice.uri").getOrElse("akka.tcp://CentralappPush@127.0.0.1:5000")
  val protocol = Play.current.configuration.getString("pushservice.protocol").getOrElse("akka.tcp")
  val pushSystem = Play.current.configuration.getString("pushservice.system").getOrElse("CentralappPush")
  val ip = Play.current.configuration.getString("pushservice.ip").getOrElse("127.0.0.1")
  val port = Play.current.configuration.getInt("pushservice.port").getOrElse(5000)
  val rootPath = Play.current.configuration.getString("pushservice.path.root").getOrElse("user")
  val actorPath = Play.current.configuration.getString("pushservice.path.actor").getOrElse("PushMaster")
  val selectionPath = RootActorPath(new Address(protocol, pushSystem, ip, port)) / rootPath / actorPath
  val pushActor = context.actorSelection(selectionPath)

  def receive = {
    case pprs: List[PlaceProvider] => {
      log.info("I received something")
      pushActor ! pprs.map(_.clone)
      context become afterSend
    }
  }

  def afterSend: Receive = {
    case pprs: List[PlaceProvider] => {
      pprs.foreach(_.update) // update in the db
      context.stop(self)
    }
    case _ => {
      log.info("Did not understand message")
      context.stop(self)
    }
  }
}

演员是在 Play! 的控制器中使用唯一名称创建的!框架。我所看到的是,当演员第一次创建位置更新时,它会完成工作并按预期进入关闭上下文。在 play 框架内第二次调用相同的操作会导致:

    [ERROR] [02/18/2015 12:32:46.181] [application-akka.actor.default-dispatcher-2] [akka://application/user/OlD1vFKVLn1424259166159] null
java.lang.NullPointerException
    at actors.CoreActor$$anonfun$receive.applyOrElse(CoreActor.scala:29)
    at akka.actor.Actor$class.aroundReceive(Actor.scala:465)
    at actors.CoreActor$.aroundReceive(CoreActor.scala:11)
    at akka.actor.ActorCell.receiveMessage(ActorCell.scala:516)
    at akka.actor.ActorCell.invoke(ActorCell.scala:487)
    at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:238)
    at akka.dispatch.Mailbox.run(Mailbox.scala:220)
    at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:393)
    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)

真是莫名其妙。为什么会这样?为什么只有在第二次启动同类型的actor时才会出现?

您的演员是 object - 这强制执行演员的单个实例。当一个 actor 停止时,它会经过一些处理来清理它的资源。由于在您的下一个请求中,您尝试使用创建失败的同一实例重新创建一个新演员。

尝试将其更改为 class

class CoreActor extends Actor with ActorLogging {
}