This is a little bit difficult to describe but I'll try my best. Now I have first an string of a class name, which is actually a custom actor class extends the akka Actor. And to instantiate it, use the following code to inject ThreadLocal during instantiate:
object helper {
private val context = new ThreadLocal[Option[String]]()
def createContext[T <: Actor](s: String, creator: => T): T = {
context.set(Some(s))
val r = creator
context.set(None)
r
}
}
And then I try to start the actor from a string of classname like following:
val myclassname = "com.myorg.mypkg.myactor"
val myclazz = Class.forName(myclassname) asSubclass classOf[Actor]
val props = Props { helper.createContext("mycontext") { myclazz.newInstance() }}
val act = system.actorOf(props)
act ! "some message"
This will be OK for a normal actor with default mailbox type. But when I define a class with Stash mixed in, due to the problem of ClassTag can't figure out the correct type parameter. When calling "asSubclass", the Stash trait information is lost, and actorOf call will throw out an exception of: DequeBasedMailbox required, got: akka.dispatch.UnboundedMailbox$MessageQueue.
Props.apply(Class[_], args*) can resolve this problem but that will not allow an injecting of instantiate. Both props.create with creator and props.apply with creator function will require a type parameter extends Actor, and that can't be fulfilled due to the class is reflected from string. Any idea?
Aucun commentaire:
Enregistrer un commentaire