Reputation: 2847
Is it prohibited by design or am I doing something wrong?
val ext = 1
class Test extends Actor {
def receive = { case _ => println(ext) }
}
try {
val sys = ActorSystem("lol")
sys.actorOf(Props[Test], "test") ! true
} catch {
case e: Throwable => println(e)
}
once I send a message to Test
I get an exception java.lang.IllegalArgumentException: no matching constructor found on class HelloAkkaScala$Test$1 for arguments []
.
I don't have this exception if I don't reference ext
inside of Test
class.
I'm using Akka 2.3.4
Upvotes: 0
Views: 91
Reputation: 12446
There is nothing wrong in accessing val
(not var
or any other mutable state) defined outside of the actor.
Just tried to run your example code in Akka 2.3.5 and it works fine. You probably have a typo somwhere in your original code.
UPDATE
Looking closer at the error you are getting it seems like you've defined Test
class inside some other class.
In this case inner class (Test
) will receive reference to outer class behind the scenes in order to be able to close on it's members (ext
).
This also means that constructor of the inner class will take reference to the outer class (syntactic sugar hides this).
This also explains why you are getting the error (you pass 0 args to constructor but there actually some hidden ones that you are not supplying).
Here is the example that reproduces this:
class Boot {
val ext = 1
class Test extends Actor {
def receive = { case _ => println(ext) }
}
try {
val sys = ActorSystem("lol")
sys.actorOf(Props[Test], "test") ! true
} catch {
case e: Throwable => println(e)
}
}
object Boot extends App {
new Boot
}
... and here is a quick workaround (in this case I make Test
and ext
"static" by moving them to companion object, but you can achieve similar results by referencing ext
as a member of some other instance, passed to constructor):
class Boot {
import Boot.Test
try {
val sys = ActorSystem("lol")
sys.actorOf(Props[Test], "test") ! true
} catch {
case e: Throwable => println(e)
}
}
object Boot extends App {
val ext = 1
class Test extends Actor {
def receive = { case _ => println(ext) }
}
new Boot
}
Upvotes: 2