2

以下のようなスケジューラがあります。これは、アクター システム内の別のアクターに 30 分ごとにメッセージを送信するためのものです。このコードは、scala の Eclipse IDE で実行すると正常に動作します。ただし、MicroKernel でこのコードをスローすると (Microkernel が起動できるようにブータブルを使用して)、次のような例外が発生します。

java.lang.NoSuchMethodError: akka.actor.ActorSystem.dispatcher()Lscala/concurrent/ExecutionContext; 完全なスタック トレースを以下に示します。この問題は、このコンテキストでは無効な「import system.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)
4

3 に答える 3

1

コメントでのローランドの答えは正しいものです。Scala の java.lang.NoSuchMethodError は通常、バイナリ互換性のないライブラリを使用していることを意味します。

IDE プロジェクトと Microkernel アプリで異なるメジャー Scala バージョンを使用するか、異なるメジャー Akka バージョンを使用します。

于 2013-07-29T08:49:39.037 に答える
1

私のコードの問題は、ActorSystem を作成しようとしていたことです。

import system.dispatcher がコードが失敗した理由です。

代わりに、行 import scala.concurrent.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.")}

}
}
于 2013-07-27T14:52:43.027 に答える