我正在尝试从外部 jar 动态加载演员,然后将该演员启动到 ActorSystem 中。我想要一个用于加载演员的插件式架构。到目前为止,我尝试了以下代码:
val loader = new URLClassLoader(Array(new URL("file:///<path>/plugin.jar")))
val clazz = loader.loadClass("d2e.Inst").asInstanceOf[Class[Actor]]
这部分工作正常,但是如果我启动 ActorSystem 并尝试启动我的新演员:
val system = ActorSystem.create("mysys")
val actor = system.actorOf(Props(clazz), "myactor")
我得到以下异常:
akka.ConfigurationException: configuration problem while creating
...
Caused by: java.lang.IllegalArgumentException: unknown actor creator [class d2e.Inst]
at akka.actor.Props.cachedActorClass(Props.scala:207)
at akka.actor.Props.actorClass(Props.scala:327)
at akka.dispatch.Mailboxes.getMailboxType(Mailboxes.scala:124)
at akka.actor.LocalActorRefProvider.actorOf(ActorRefProvider.scala:718)
深入研究 Props.scala 文件,我发现错误是由使用 isAssignableFrom 引起的。我对其进行了一些测试,发现存在以下令人困惑的行为:
println(clazz.isInstanceOf[Class[Actor]]) // returns true
println(classOf[Actor].isAssignableFrom(clazz)) // returns false
有没有办法解决这种行为?我猜这与系统类加载器和 URL 类加载器中定义的 Actor 类有关。我的插件尝试甚至可能吗?
哦,我正在使用带有 scala 2.10.2 的 akka 2.2.1
编辑
为了澄清一点,clazz.isInstanceOf[Class[Actor]]
由于类型擦除,这对任何事情都是正确的。