Akka:上下文会抛出NullPointerException吗?

时间:2015-02-18 11:39:05

标签: akka actor

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

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中的控制器内的唯一名称创建actor!框架。我所看到的是,当第一次创建一个演员更新时,它会完成它的工作并按预期进入关闭环境。在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$1.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)

这令人费解。为什么会这样?为什么它只在第二次启动相同类型的演员时才会发生?

1 个答案:

答案 0 :(得分:5)

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

尝试将其更改为class

class CoreActor extends Actor with ActorLogging {
}