smeeb smeeb - 27 days ago 7
Groovy Question

Java Akka Scheduling API throwing MissingMethodException

Java 8 (well, Groovy) using Akka

com.typesafe.akka:akka-actor_2.11:2.5.4
here. I'm trying to create an actor (
AppMaster
) that creates/owns/manages another actor (
StateChecker
) and is scheduled to send this
StateChecker
a
CheckState
message every 4 seconds:

class CheckState {}

class StateChecker extends AbstractActor {
// For this question, it really doesn't matter what this actor does
}

class AppMaster extends AbstractActor {
ActorRef stateChecker

@Override
Receive createReceive() {
receiveBuilder()
.match(Init, { message ->
stateChecker = context.actorOf(Props.create(StateChecker, "yes", 20), "state-checker")

FiniteDuration startDur = Duration.Zero()

FiniteDuration freqDur = Duration.create(4000, TimeUnit.MILLISECONDS)
CheckState checkState = new CheckState()
ExecutionContextExecutor executor = context.system().dispatcher()

context.system().scheduler().schedule(startDur, freqDur, stateChecker, checkState,
executor)
})
.build()
}
}


When I run this I get the following exception:

groovy.lang.MissingMethodException: No signature of method: akka.actor.LightArrayRevolverScheduler.schedule() is applicable for argument types: (scala.concurrent.duration.FiniteDuration, scala.concurrent.duration.FiniteDuration, akka.actor.LocalActorRef, com.me.myapp.messages.CheckState, akka.dispatch.Dispatcher) values: [0 days, 4000 milliseconds, Actor[akka://myapp/user/myapp-master/o1-keeper#-1837899613], ...]
Possible solutions: schedule(scala.concurrent.duration.FiniteDuration, scala.concurrent.duration.FiniteDuration, java.lang.Runnable, scala.concurrent.ExecutionContext), schedule(scala.concurrent.duration.FiniteDuration, scala.concurrent.duration.FiniteDuration, scala.Function0, scala.concurrent.ExecutionContext), schedule(scala.concurrent.duration.FiniteDuration, scala.concurrent.duration.FiniteDuration, akka.actor.ActorRef, java.lang.Object, scala.concurrent.ExecutionContext, akka.actor.ActorRef)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:58)
at org.codehaus.groovy.runtime.callsite.PojoMetaClassSite.call(PojoMetaClassSite.java:49)


I added in log statements and the exception is being thrown during the scheduling:

context.system().scheduler().schedule(startDur, freqDur, stateChecker, checkState,
executor)


Any idea what I need to do to fix this? Since this is an issue I'm having with Akka's Java API, I do need the answer to be via the Java API... thanks in advance!

Answer Source

The problem is that the arguments that you're passing to the schedule() method match none of the overloaded versions of that method. You can see the signatures of the overloaded versions of schedule() in the JavaDoc.

The version that you're trying to use is the following method:

Cancellable schedule(scala.concurrent.duration.FiniteDuration initialDelay,
                     scala.concurrent.duration.FiniteDuration interval,
                     ActorRef receiver,
                     java.lang.Object message,
                     scala.concurrent.ExecutionContext executor,
                     ActorRef sender)

You're missing the last parameter, which is an ActorRef that is designated as the sender of the scheduled message. If StateChecker doesn't care who sends it the CheckState message, then the easiest fix is to pass in null as this last parameter:

context.system()
       .scheduler()
       .schedule(startDur, freqDur, stateChecker, checkState, executor, null)
                                                                     // ^