a scala remote actor exception - scala

i with a scala code like this for echo service.
import scala.actors.Actor
import scala.actors.Actor._
import scala.actors.remote.RemoteActor._
class Echo extends Actor {
def act() {
alive(9010)
register('myName, self)
loop {
react {
case msg => println(msg)
}
}
}
}
object EchoServer {
def main(args: Array[String]): unit = {
val echo = new Echo
echo.start
println("Echo server started")
}
}
EchoServer.main(null)
but there has some exception.
java.lang.NoClassDefFoundError: Main$$anon$1$Echo$$anonfun$act$1
at Main$$anon$1$Echo.act((virtual file):16)
at scala.actors.Reaction.run(Reaction.scala:76)
at scala.actors.Actor$$anonfun$start$1.apply(Actor.scala:785)
at scala.actors.Actor$$anonfun$start$1.apply(Actor.scala:783)
at scala.actors.FJTaskScheduler2$$anon$1.run(FJTaskScheduler2.scala:160)
at scala.actors.FJTask$Wrap.run(Unknown Source)
at scala.actors.FJTaskRunner.scanWhileIdling(Unknown Source)
at scala.actors.FJTaskRunner.run(Unknown Source)
Caused by: java.lang.ClassNotFoundException: Main$$anon$1$Echo$$anonfun$act$1
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:320)
... 8 more
i don't konw how can cause it.
by the way .my scala version is 2.7.5

ClassNotFoundException indicates that something was probably not compiled, that should have been compiled. How did you compile it? Manually using scalac?
Try the following rm *.class scalac *.scala scala EchoServer.
The following works:
EchoServer.scala
import scala.actors.Actor
import scala.actors.Actor._
import scala.actors.remote.RemoteActor._
class Echo extends Actor {
def act() {
alive(9010)
register('myName, self)
loop {
react {
case msg => println(msg)
}
}
}
}
object EchoServer {
def main(args: Array[String]): unit = {
val echo = new Echo
echo.start
println("Echo server started")
}
}
Client.scala
import scala.actors.Actor._
import scala.actors.remote.Node
import scala.actors.remote.RemoteActor._
object Client extends Application {
override def main(args: Array[String]) {
if (args.length < 1) {
println("Usage: scala Client [msg]")
return
}
actor {
val remoteActor = select(Node("localhost", 9010), 'myName)
remoteActor !? args(0) match {
case msg => println( "Server's response is [" + msg + "]" )
}
}
}
}
Command line:
rm *.class && scalac *.scala && scala EchoServer
And in other terminal:
scala Client hello

You need to set the classloader on the remote actors.
Before the act() method, add the line:
RemoteActor.classLoader = getClass.getClassLoader
Why is setting the classloader necessary with Scala RemoteActors?

Related

How to use Using (with Source.fromFile) and handle error

This is a follow up question to https://stackoverflow.com/a/55440851/2691976
I have the following code
import scala.io.Source
import scala.util.Using
object Problem {
def main(args: Array[String]): Unit = {
Using(Source.fromFile("thisfileexists.txt")) { source =>
println(1 / 1)
println(1 / 0)
}
}
}
Running it with scala3, it will just print out 1 single line and no error.
scala3 test.scala
1
I am expecting an error like the following,
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Problem$.main(test.scala:10)
at Problem.main(test.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at dotty.tools.scripting.ScriptingDriver.compileAndRun(ScriptingDriver.scala:42)
at dotty.tools.scripting.Main$.main(Main.scala:43)
at dotty.tools.MainGenericRunner$.run$1(MainGenericRunner.scala:230)
at dotty.tools.MainGenericRunner$.main(MainGenericRunner.scala:239)
at dotty.tools.MainGenericRunner.main(MainGenericRunner.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at coursier.bootstrap.launcher.a.a(Unknown Source)
at coursier.bootstrap.launcher.Launcher.main(Unknown Source)
So why does it not print out error when I am using Using (which I suspect it is causing the problem here)?
And what is the solution so I can use both Using and Source.fromFile with potential error?
I have read the Using Scala 2 doc and Scala 3 doc but it doesn't say anything about error
In case this is important, I am using Mac
scala3 --version
Scala code runner version 3.1.2-RC1-bin-20211213-8e1054e-NIGHTLY-git-8e1054e -- Copyright 2002-2021, LAMP/EPFL
Thats because Using returns Try as you can see here
https://www.scala-lang.org/api/2.13.x/scala/util/Using$.html#apply[R,A](resource:=%3ER)(f:R=%3EA)(implicitevidence$1:scala.util.Using.Releasable[R]):scala.util.Try[A]
You can use .fold, .get, pattern matching, etc.
for example:
import scala.io.Source
import scala.util.Using
object Problem {
def main(args: Array[String]): Unit = {
Using(Source.fromFile("thisfileexists.txt")) { source =>
println(1 / 1)
println(1 / 0)
}.get
}
}
or as follows:
import scala.io.Source
import scala.util.Using
import scala.util._
object Problem {
def main(args: Array[String]): Unit = {
Using(Source.fromFile("thisfileexists.txt")) { source =>
println(1 / 1)
println(1 / 0)
} match {
case Success(res) => println("Do something on sucess")
case Failure(ex) => println(s"Failed with ex: ${ex.getMessage}")
}
}
}
You can read more about Try at scala:
https://www.scala-lang.org/api/2.13.x/scala/util/Try.html

No such method error akka.util.Helpers$.toRootLowerCase(Ljava/lang/String;)Ljava/lang/String;

I am trying to run the following program
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
import akka.http.scaladsl.marshalling.ToResponseMarshallable
import akka.http.scaladsl.model.{ContentTypes, HttpEntity}
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.directives.BasicDirectives
import akka.io.IO
import akka.stream.ActorMaterializer
import com.typesafe.config.ConfigFactory
import spray.json.DefaultJsonProtocol
import scala.concurrent.duration._
import scala.concurrent.Await
trait JsonSupport extends SprayJsonSupport with DefaultJsonProtocol {
implicit val itemFormat = jsonFormat2(Item)
}
final case class Item(name: String, id: Long)
object Main extends App with RestInterface {
val config = ConfigFactory.load()
val host = config.getString("http.host")
val port = config.getInt("http.port")
implicit val system = ActorSystem("My-ActorSystem")
implicit val executionContext = system.dispatcher
implicit val materializer = ActorMaterializer()
//implicit val timeout = Timeout(10 seconds)
val api = routes
Http().bindAndHandle(api, host, port) map {
binding => println(s"The binding local address is ${binding.localAddress}")
}
// recover
// { case ex => println(s"some shit occurred and it is"+ex.getMessage) }
// sys.addShutdownHook {
// system.log.info("Shutting down Spray HTTP in 10 seconds...")
// // NOTE(soakley): We are waiting to unbind to allow the VIP time to query healthcheck status.
// Thread.sleep(10000)
// system.log.info("Shutting down Spray HTTP and allowing 10 seconds for connections to drain...")
// val unbindFuture = Http.unbind(10.seconds)
//
// Await.ready(unbindFuture, 10.seconds)
// }
}
case class Stringer(str1 : String, str2 : String, str3 : String)
trait RestInterface extends Resource {
val routes = questionroutes ~ mydirectiveroute01 ~ mydirectiveroute02
}
trait Resource extends QuestionResource with mydirective01 with mydirective02
trait QuestionResource {
val questionroutes = {
path("hi") {
get {
val stringer_instance = Stringer("questionairre created","whatever","whatever-whatever")
complete(ToResponseMarshallable(stringer_instance.toString()))
}
}
}
}
trait mydirective01 extends BasicDirectives {
val getandputdirective = get | put
val mydirectiveroute01 = {
path("customhi" / IntNumber) {
passednumber1 => {
path(IntNumber) {
passednumber2 => {
getandputdirective {
ctx =>
ctx.complete("Testing get and put directive" + s"The passed string is " + passednumber2 + passednumber1)
}
}
}
}
}
}
}
trait mydirective02 extends BasicDirectives with JsonSupport {
val mydirectiveroute02 =
path("hello") {
get {
complete(HttpEntity(
ContentTypes.`text/html(UTF-8)`,
"<h1>Say hello to akka-http</h1>"))
}
} ~
path("randomitem") {
get {
// will marshal Item to JSON
complete(Item("thing", 42))
}
} ~
path("saveitem") {
post {
// will unmarshal JSON to Item
entity(as[Item]) { item =>
println(s"Server saw Item : $item")
complete(item)
}
}
}
}
But I get the following error
Exception in thread "main" java.lang.NoSuchMethodError: akka.util.Helpers$.toRootLowerCase(Ljava/lang/String;)Ljava/lang/String;
The error seems to be because of this line
implicit val materializer = ActorMaterializer()
May I know where I am going wrong. I have identical pom.xml file and the program in another module and it seems to run fine. I dont understand where I am going wrong. Thanks
I get errors like that when something that should have been re-compiled has not been re-compiled. clean" followed by "compile" in sbt resolves it.
The issue is due to the conflict in dependencies make sure you are using same version for all the related packages you are importing.
example:
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-http-core_2.11</artifactId>
<version>10.0.0</version>
</dependency>
2.11 make sure you have other dependencies with same version
then make a clean build.
Your project dependencies have conflicting versions. The version that has that function gets discarded, and the other version included in the jar (or classpath - depending on how you execute).
Please provide your dependencies file (i.e. sbt.build or gradle.build etc.)

How can a custom ApplicationLoader start Dependency Injecting Actors and get tested?

In "Dependency Injecting Actors" it's shown how to inject a parameter into the constructor of a child actor. The parent actor uses injectedChild to be allowed to pass to the child (at child creation time) only the non-injected parameter and then let Guice inject the rest. To do this, it extends InjectedActorSupport and gets the child's factory injected in the constructor:
class MyParent #Inject() (childFactory: MyChild.Factory,
#Assisted something: Something,
#Assisted somethingElse: SomethingElse) extends Actor with InjectedActorSupport
[..]
val child: ActorRef = injectedChild(childFactory(something, somethingElse), childName)
But what about the class that starts the parent and is not an actor but a custom ApplicationLoader?
How can I start the parent actor from there? No mention of this is in the documentation.
I tried doing the same for the loader as I did for parent:
class MyLoader #Inject() (parentFactory: MyParent.Factory) extends ApplicationLoader with Actor with InjectedActorSupport {
[..]
val parent = injectedChild(parentFactory(something, somethingElse), parentName)
would this be correct? How can I test it?
class MyModule extends AbstractModule with AkkaGuiceSupport {
def configure = {
bindActor[MyParent](parentName)
bindActor[MyLoader](loaderName)
bindActorFactory[MyChild, MyChild.Factory]
bindActorFactory[MyParent, MyParent.Factory]
}
}
So:
How do I start the parent from MyLoader while letting Guice dependency-inject what's required?
How can I test MyLoader?
This has been my test so far but now I need to pass the injected thingy to MyLoader and I don't know how (note the ***???**** in place of the argument which I do not know where to find):
class MyLoaderSpec(_system: ActorSystem, implicit val ec: ExecutionContext) extends TestKit(_system) with WordSpecLike with BeforeAndAfterAll with Matchers {
val loader = new SimstimLoader(???)
override def beforeAll(): Unit = {
loader.load(ApplicationLoader.createContext(new Environment(new File("."), ApplicationLoader.getClass.getClassLoader, Mode.Test)))
}
Thanks a million in advance!
Here is how I solved this issue.
--> How to start a parent actor who needs dependency-injection.
First of all, manually starting such an actor is impossible if you, like me, need to dependency-inject an instance which you do not know how to pass and where from. The solution is to let Guice start the actor automagically. Here is how.
First, create your binder module for Guice:
class MyModule extends AbstractModule with AkkaGuiceSupport{
override def configure(): Unit = {
bindActor[Root](Root.NAME)
bind(classOf[StartupActors]).asEagerSingleton()
}
}
Then, tell Play where your binder module is located by adding the following in your conf/application.conf:
play.modules={
enabled += "my.path.to.MyModule"
}
The StartupActors is simply a class I use to log whenever the automagic start of dependency-injected actors actually takes place. I log the event so that I can be sure of when and whether it occurs:
class StartupActors #Inject() (#Named(Root.NAME) root: ActorRef) {
play.api.Logger.info(s"Initialised $root")
}
The Root actor in my case takes care of parsing a custom configuration. Since the resulting vars from the parsing is required by my parent actor and during the tests I need to mock such resulting vars, I delegate the parsing to an actor other than the parent actor, i.e., the Root actor:
object Root {
final val NAME = "THERoot"
case class ParseConfiguration()
}
class Root #Inject()(configuration: Configuration, projectDAO: ProjectDAO) extends Actor {
val resultingVar: Something = myConfigParsing()
override def preStart(): Unit = {
context.actorOf(Props(new MyParent(resultingVar: Something, somethingElse: SomethingElse, projectDAO: ProjectDAO)))
}
override def receive: Receive = {
case ParseConfiguration => sender ! myConfigParsing()
case _ => logger.error("Root actor received an unsupported message")
}
}
The ParseConfiguration message is used uniquely for testing purposes. Normally the configuration parsing occurs instead because of the initialisation of the resultingVar attribute.
This way, MyParent wont need to get anything injected. Only StartupActors and Root will get injected. MyParent will simply get projectDAO from Root and pass it on to all its children.
class MyParent(something: Something, somethingElse: SomethingElse, projectDAO: ProjectDAO) extends Actor { ... }
Finally, for completion, I'm reporting here how I wrote the tests since I had troubles finding enough information online around this as well.
import akka.actor.{ActorRef, ActorSystem, Props}
import akka.testkit.{TestKit, TestProbe}
import com.typesafe.config.ConfigFactory
import org.mockito.Mockito.mock
import org.scalatest.{BeforeAndAfterAll, WordSpecLike}
import org.specs2.matcher.MustMatchers
import play.api.Configuration
import scala.concurrent.ExecutionContext
class RootSpec(_system: ActorSystem) extends TestKit(_system)
with WordSpecLike with BeforeAndAfterAll with MustMatchers {
implicit val ec: ExecutionContext = scala.concurrent.ExecutionContext.global
val conf: com.typesafe.config.Config = ConfigFactory.load()
val configuration: Configuration = Configuration(conf)
val projectDAOMock: ProjectDAO = mock(classOf[ProjectDAO])
private var mainActor: ActorRef = _
private var something: Something = Something.empty
def this() = this(ActorSystem("MySpec"))
override def afterAll: Unit = {
system.shutdown()
}
override def beforeAll(): Unit = {
mainActor = system.actorOf(Props(new Root(configuration, projectDAOMock)), Root.NAME)
}
"RootSpec: Root Actor" should {
val probe = TestProbe()
"successfully parse the configuration file" in {
probe.send(mainActor, ParseConfiguration)
something = probe.expectMsgPF() {
case msg => msg.asInstanceOf[Something]
}
}
}
}
and then I test MyParent by conveniently providing mock objects in place of vars resulting from the configuration parsing:
import akka.actor.{ActorRef, ActorSystem, Props}
import akka.testkit.{TestKit, TestProbe}
import org.mockito.Mockito
import org.mockito.Mockito._
import org.scalatest.{BeforeAndAfterAll, WordSpecLike}
import org.specs2.matcher.MustMatchers
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.{ExecutionContext, Future}
case class AnyProjectAPI(val projectAPI: ProjectAPI) extends AnyVal
class MyParentSpec(_system: ActorSystem, implicit val ec: ExecutionContext) extends TestKit(_system)
with WordSpecLike with BeforeAndAfterAll with MustMatchers {
val something = mock(classOf[Something])
val somethingElse = mock(classOf[somethingElse])
val projectDAOMock: ProjectDAO = mock(classOf[ProjectDAO])
val projectTest: ProjectAPI = new ProjectAPI(allMyRandomConstructorArguments),
val projectsList: List[ProjectAPI] = List(projectTest)
val expectedCreationId = 1
private var parent: ActorRef = _
def this() = this(ActorSystem("MySpec"), scala.concurrent.ExecutionContext.global)
override def afterAll: Unit = {
system.shutdown()
}
override def beforeAll(): Unit = {
parent = system.actorOf(Props(new MyParent(something, somethingElse, projectDAOMock)), MyParent.NAME)
}
"MyParentTesting: parent's pull request" should {
when(myProjApi.getAllProjects).thenReturn(Future {projectsList})
val anyProject: AnyProjectAPI = AnyProjectAPI(org.mockito.Matchers.any[ProjectAPI])
Mockito.when(projectDAOMock.create(org.mockito.Matchers.any[ProjectAPI]))
.thenReturn(Future {expectedCreationId}: Future[Int])
val probe = TestProbe()
val probe1 = TestProbe()
"be successfully satisfied by all children when multiple senders are waiting for an answer" in {
probe.send(parent, UpdateProjects)
probe1.send(parent, UpdateProjects)
allChildren.foreach(child =>
probe.expectMsg(expectedCreationId))
allChildren.foreach(child =>
probe1.expectMsg(expectedCreationId))
}
}
}

Camel routing to akka endpoint throws ActorNotRegisteredException

I want to set camel endpoint to akka component like akka://some-system/user/myactor
I have following code:
package rsmev
import akka.actor.{ActorRef, Actor, Props, ActorSystem}
import akka.camel.{CamelExtension, CamelMessage, Consumer}
import org.apache.camel.builder.RouteBuilder
object Frontend {
def main(args: Array[String]) {
val system = ActorSystem("my_system")
val actor = system.actorOf(Props[ConsumerActor], "myconsumer")
val context = CamelExtension(system).context
context.addRoutes(new RouteBuilder() {
override def configure(): Unit = {
from("direct:start")
.to("akka://my_system/user/myconsumer")
}
})
context.start()
Thread.sleep(10 * 1000)
val producer = context.createProducerTemplate()
producer.sendBody("direct:start", "HELLO!")
Thread.sleep(10 * 1000)
}
}
class ConsumerActor extends Actor {
override def receive = {
case _ => println("OK")
}
}
When executing this code I get:
akka.camel.ActorNotRegisteredException: Actor [akka://survex_system/user/myconsumer] doesn't exist
at akka.camel.internal.component.ActorProducer$$anonfun$actorFor$1.apply(ActorComponent.scala:175)
at akka.camel.internal.component.ActorProducer$$anonfun$actorFor$1.apply(ActorComponent.scala:175)
at scala.Option.getOrElse(Option.scala:121)
at akka.camel.internal.component.ActorProducer.actorFor(ActorComponent.scala:175)
at akka.camel.internal.component.ActorProducer.fireAndForget(ActorComponent.scala:172)
at akka.camel.internal.component.ActorProducer.processExchangeAdapter(ActorComponent.scala:143)
at akka.camel.internal.component.ActorProducer.process(ActorComponent.scala:120)
at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:113)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:416)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
at org.apache.camel.component.direct.DirectProducer.process(DirectProducer.java:51)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
at org.apache.camel.processor.UnitOfWorkProducer.process(UnitOfWorkProducer.java:73)
at org.apache.camel.impl.ProducerCache$2.doInProducer(ProducerCache.java:375)
at org.apache.camel.impl.ProducerCache$2.doInProducer(ProducerCache.java:343)
at org.apache.camel.impl.ProducerCache.doInProducer(ProducerCache.java:233)
at org.apache.camel.impl.ProducerCache.sendExchange(ProducerCache.java:343)
at org.apache.camel.impl.ProducerCache.send(ProducerCache.java:184)
at org.apache.camel.impl.DefaultProducerTemplate.send(DefaultProducerTemplate.java:124)
at org.apache.camel.impl.DefaultProducerTemplate.sendBody(DefaultProducerTemplate.java:137)
at org.apache.camel.impl.DefaultProducerTemplate.sendBody(DefaultProducerTemplate.java:144)
at rsmev.Frontend$.main(Frontend.scala:17)
at rsmev.Frontend.main(Frontend.scala)
Exception in thread "main" org.apache.camel.CamelExecutionException: Exception occurred during execution on the exchange: Exchange[Message: HELLO!]
at org.apache.camel.util.ObjectHelper.wrapCamelExecutionException(ObjectHelper.java:1379)
at org.apache.camel.util.ExchangeHelper.extractResultBody(ExchangeHelper.java:623)
at org.apache.camel.impl.DefaultProducerTemplate.extractResultBody(DefaultProducerTemplate.java:467)
at org.apache.camel.impl.DefaultProducerTemplate.extractResultBody(DefaultProducerTemplate.java:463)
at org.apache.camel.impl.DefaultProducerTemplate.sendBody(DefaultProducerTemplate.java:139)
at org.apache.camel.impl.DefaultProducerTemplate.sendBody(DefaultProducerTemplate.java:144)
at rsmev.Frontend$.main(Frontend.scala:17)
at rsmev.Frontend.main(Frontend.scala)
Caused by: akka.camel.ActorNotRegisteredException: Actor [akka://survex_system/user/myconsumer] doesn't exist
at akka.camel.internal.component.ActorProducer$$anonfun$actorFor$1.apply(ActorComponent.scala:175)
at akka.camel.internal.component.ActorProducer$$anonfun$actorFor$1.apply(ActorComponent.scala:175)
at scala.Option.getOrElse(Option.scala:121)
at akka.camel.internal.component.ActorProducer.actorFor(ActorComponent.scala:175)
at akka.camel.internal.component.ActorProducer.fireAndForget(ActorComponent.scala:172)
at akka.camel.internal.component.ActorProducer.processExchangeAdapter(ActorComponent.scala:143)
at akka.camel.internal.component.ActorProducer.process(ActorComponent.scala:120)
at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:113)
at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:416)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
at org.apache.camel.component.direct.DirectProducer.process(DirectProducer.java:51)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
at org.apache.camel.processor.UnitOfWorkProducer.process(UnitOfWorkProducer.java:73)
at org.apache.camel.impl.ProducerCache$2.doInProducer(ProducerCache.java:375)
at org.apache.camel.impl.ProducerCache$2.doInProducer(ProducerCache.java:343)
at org.apache.camel.impl.ProducerCache.doInProducer(ProducerCache.java:233)
at org.apache.camel.impl.ProducerCache.sendExchange(ProducerCache.java:343)
at org.apache.camel.impl.ProducerCache.send(ProducerCache.java:184)
at org.apache.camel.impl.DefaultProducerTemplate.send(DefaultProducerTemplate.java:124)
at org.apache.camel.impl.DefaultProducerTemplate.sendBody(DefaultProducerTemplate.java:137)
... 3 more
I can't figure out why does this happen, because actor myconsumer is registered.
Finally figured out what the problem was - you don't need to start camel context, this is the right way of usage:
package rsmev
import akka.actor.{ActorRef, Actor, Props, ActorSystem}
import akka.camel.{CamelExtension, CamelMessage, Consumer}
import org.apache.camel.builder.RouteBuilder
import akka.camel._
object Frontend {
def main(args: Array[String]) {
val system = ActorSystem("system")
val actor = system.actorOf(Props[ConsumerActor], "myconsumer")
val context = CamelExtension(system).context
context.addRoutes(new RouteBuilder() {
override def configure(): Unit = {
from("direct:start")
.to("akka://system/user/myconsumer")
}
})
Thread.sleep(5 * 1000)
val producer = context.createProducerTemplate()
producer.sendBody("direct:start", "HELLO!")
Thread.sleep(10 * 1000)
}
}
class ConsumerActor extends Actor {
override def receive = {
case _ => println("OK")
}
}

Could not execute this Akka actor based test code

I am new to Scala Akka actor. Based on the akka tutorial example on their website,i coded a similar example with just printing messages with the time they started. But the code does not get executed in my eclipse IDE.
import akka.actor.Actor
import akka.actor.ActorRef
import scala.collection.mutable.ListBuffer
import akka.actor.Props
import akka.routing.RoundRobinRouter
import akka.actor.ActorSystem
object AkaObj extends App{
process()
sealed trait PiMessage
case class Work(value:String) extends PiMessage
case class printComp(valu:String)extends PiMessage
case object Start extends PiMessage
case class ListObj(cont:Seq[String]) extends PiMessage
class Worker extends Actor{
def receive()={
case Work(value:String)=>
println(value)
sender ! printComp(value)
}
}
class Master(listener: ActorRef) extends Actor{
val nrOfWorkers = 10
var counter = 0
var lis = ListBuffer[String]()
val workerRouter = context.actorOf(
Props[Worker].withRouter(RoundRobinRouter(nrOfWorkers)), name = "workerRouter")
def receive()={
//handle message
case Start=>workerRouter ! Work("Start now " + System.currentTimeMillis())
case printComp(value:String)=> {
counter+=1
lis.append(counter+"-"+value)
if(counter >=10)
listener ! ListObj(lis.toSeq)
// Stops this actor and all its supervised children
context.stop(self)
}
}
}
class Listener extends Actor{
def receive()={
case ListObj(cont:Seq[String])=>
println("Completed " +cont)
context.system.shutdown()
}
}
def process(){
// Create an Akka system
val system = ActorSystem("PiSystem")
// create the result listener, which will print the result and shutdown the system
val listener = system.actorOf(Props[Listener], name = "listener")
// create the master
val master = system.actorOf(Props(new Master(listener)),
name = "master")
// start the calculation
master ! Start
}
}
Issue: The error message i get is: "Error: Could not find or load main class AkaObj"
It does not even compiling i think. When i run the project,that's the message i get.
Actually, I managed to run your code just after dependencies were resolved. So the problem is in your environment configuration. I use Intellij Idea IDE.
Try this Eclipse Error: Could not find or load main class
The actual problem is the use of object AkaObj extends App. When programming scala I have noticed that using scala.App is restricted to simple programs (at least in IDEs). As soon as you start defining objects and classes inside scala.App Eclipse starts complaining about not finding the entry point of the program.
Try to fix this as follows:
import akka.actor.Actor
import akka.actor.ActorRef
import scala.collection.mutable.ListBuffer
import akka.actor.Props
import akka.routing.RoundRobinRouter
import akka.actor.ActorSystem
object AkaObj {
def main(args:Array[String]) {
process()
}
def process() {
// Create an Akka system
val system = ActorSystem("PiSystem")
// create the result listener, which will print the result and shutdown the system
val listener = system.actorOf(Props[Listener], name = "listener")
// create the master
val master = system.actorOf(Props(new Master(listener)),
name = "master")
// start the calculation
master ! Start
}
sealed trait PiMessage
case class Work(value:String) extends PiMessage
case class printComp(valu:String)extends PiMessage
case object Start extends PiMessage
case class ListObj(cont:Seq[String]) extends PiMessage
class Worker extends Actor{
def receive()={
case Work(value:String)=>
println(value)
sender ! printComp(value)
}
}
class Master(listener: ActorRef) extends Actor{
val nrOfWorkers = 10
var counter = 0
var lis = ListBuffer[String]()
val workerRouter = context.actorOf(
Props[Worker].withRouter(RoundRobinRouter(nrOfWorkers)), name = "workerRouter")
def receive()={
//handle message
case Start=>workerRouter ! Work("Start now " + System.currentTimeMillis())
case printComp(value:String)=> {
counter+=1
lis.append(counter+"-"+value)
if(counter >=10)
listener ! ListObj(lis.toSeq)
// Stops this actor and all its supervised children
context.stop(self)
}
}
}
class Listener extends Actor{
def receive()={
case ListObj(cont:Seq[String])=>
println("Completed " +cont)
context.system.shutdown()
}
}
}
Using def main(args:Array[String]) fixes the problem in most cases.