Akka Scheduler只在MicroKernel中抛出异常,但在scala的eclipse IDE中运行良好



我有一个调度器,如下所示。它意味着每30分钟向actor系统中的另一个actor发送一条消息。当我在eclipseIDE for scala中运行这段代码时,它运行得很好。然而,当我在Microkernel中抛出这段代码(带有可引导代码,以便Microkernel可以调用它)时,我得到一个异常,说

java.lang.NoSuchMethodError:akka.actor.ActorSystem.dispatcher()Lscala/concurrent/ExecutionContext;完整的堆栈跟踪如下所示。我怀疑问题可能与"importsystem.dispatcher"行有关,该行在此上下文中无效。或者计划程序试图过早地激发消息。

请帮忙。。。

scheduler.scala:

import akka.actor.Actor
import akka.actor.Props
import scala.concurrent.duration._
import akka.actor._
import java.sql.Timestamp;
import java.util.Date;
class Scheduler extends Actor with ActorLogging {
    import transactions._
    val system = ActorSystem("Daemon")
    import system.dispatcher
    log.info("Scheduler initializing.")
    system.scheduler.schedule( 30 milliseconds, (1000*60*30 ) milliseconds){ 
                self! updateUows(new Timestamp(new java.util.Date().getTime()))}
    def receive = {
    case updateUows(time) => { 
        log.info("updateuow to be sent.")
        context.parent!updateUows(time) 
    }
    }
}

完整堆栈:

    [DEBUG] [07/26/2013 15:38:23.324] [Daemon-akka.actor.default-dispatcher-4] [EventStream(akka://Daemon)] Default Loggers started
Uncaught error from thread [Daemon-akka.actor.default-dispatcher-4] shutting down JVM since 'akka.jvm-exit-on-fatal-error' is enabled for ActorSystem[Daemon[ERROR] [07/26/2013
15:38:23.960] [Daemon-akka.actor.default-dispatcher-4] [ActorSystem(Daemon)] Uncaught error from thread [Daemon-akka.actor.default-dispatcher-4] shutting down JVM since 'akka
.jvm-exit-on-fatal-error' is enabled
java.lang.NoSuchMethodError: akka.actor.ActorSystem.dispatcher()Lscala/concurrent/ExecutionContext;
        at org.exactearth.PVDaemon.Scheduler$$anonfun$receive$1.applyOrElse(Scheduler.scala:25)
        at akka.actor.ActorCell.receiveMessage(ActorCell.scala:425)
        at akka.actor.ActorCell.invoke(ActorCell.scala:386)
        at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:230)
        at akka.dispatch.Mailbox.run(Mailbox.scala:212)
        at akka.dispatch.ForkJoinExecutorConfigurator$MailboxExecutionTask.exec(AbstractDispatcher.scala:506)
        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)
]
java.lang.NoSuchMethodError: akka.actor.ActorSystem.dispatcher()Lscala/concurrent/ExecutionContext;
        at org.exactearth.PVDaemon.Scheduler$$anonfun$receive$1.applyOrElse(Scheduler.scala:25)
        at akka.actor.ActorCell.receiveMessage(ActorCell.scala:425)
        at akka.actor.ActorCell.invoke(ActorCell.scala:386)
        at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:230)
        at akka.dispatch.Mailbox.run(Mailbox.scala:212)
        at akka.dispatch.ForkJoinExecutorConfigurator$MailboxExecutionTask.exec(AbstractDispatcher.scala:506)
        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)
Shutting down Akka...
Shutting down .............(my program)

它应该使用ActorSystem创建Actors,如下代码所示:

case object StartSched
class Test extends Actor with ActorLogging {
  def receive = {
    case StartSched =>
      context.system.scheduler.schedule( 30 milliseconds, (1000*60*30) milliseconds){
        self ! updateUows(new Timestamp(new java.util.Date().getTime()))
      }
  }
}
object Main {
  def main(args: Array[String]) {
    val sys = ActorSystem("Test")
    sys.actorOf(Props[Test])
  }
}

要在MicroKernel中启动它,您应该扩展Bootable特性并重载两种方法:startupshutdown。文档

在Actor内部创建ActorSystem是一个非常糟糕的决定

我的代码遇到的问题是它试图创建ActorSystem。

导入system.dispatcher是代码失败的原因。

相反,行import scala.current.ExecutionContext.Implicits.global给出了要使用的默认ExecutionContext。

感谢亚历克斯引导我朝着正确的方向前进。

case object StartSched
class Scheduler extends Actor with ActorLogging {
    import transactions._
    log.info("Scheduler initializing.")
    self!StartSched
    def receive = {
    case StartSched =>{
    import scala.concurrent.ExecutionContext.Implicits.global
    context.system.scheduler.schedule( 30 milliseconds, (1000*60*30) milliseconds){
        self ! updateUows(new Timestamp(new java.util.Date().getTime()))
      }
    }
    case updateUows(time) => { 
        log.info("updateuow to be sent.")
        context.parent!updateUows(time) 
    }
    case _=>{log.info("Don't know why we reached here.")}
}
}

Roland在评论中的回答是正确的。Scala中的java.lang.NoSuchMethodError通常意味着使用二进制不兼容的库。

您可以在IDE项目和Microkernel应用程序中使用不同的Scala主要版本,也可以使用不同的Akka主要版本。

相关内容

  • 没有找到相关文章

最新更新