ClassCastException:接口akka.actor.Scheduler不能从类akka.actor.LightArrayRevolverScheduler分配

时间:2016-03-29 17:20:07

标签: java akka classcastexception

我试图运行我已经在各种条件下成功运行了几个月的东西。我正在使用运行Java 7的Java应用程序中的 akka-actor_2.11 2.3.4和scala-library 2.11.7 。就像我说的,相同的代码已经工作了几个月。在最近的情况下,我得到以下内容:

java.lang.ClassCastException: interface akka.actor.Scheduler is not assignable from class akka.actor.LightArrayRevolverScheduler
at akka.actor.ReflectiveDynamicAccess$$anonfun$getClassFor$1.apply(DynamicAccess.scala:69)
at akka.actor.ReflectiveDynamicAccess$$anonfun$getClassFor$1.apply(DynamicAccess.scala:66)
at scala.util.Try$.apply(Try.scala:192)
at akka.actor.ReflectiveDynamicAccess.getClassFor(DynamicAccess.scala:66)
at akka.actor.ReflectiveDynamicAccess.createInstanceFor(DynamicAccess.scala:84)
at akka.actor.ActorSystemImpl.createScheduler(ActorSystem.scala:677)
at akka.actor.ActorSystemImpl.<init>(ActorSystem.scala:576)
at akka.actor.ActorSystem$.apply(ActorSystem.scala:142)
at akka.actor.ActorSystem$.apply(ActorSystem.scala:109)
at akka.actor.ActorSystem$.create(ActorSystem.scala:57)
at akka.actor.ActorSystem.create(ActorSystem.scala)

有问题的电话是: system= ActorSystem.create("MyActorSystem");

此调用发生在类的构造函数中,该类通过反射ala getConstructor(...).newInstance(...)动态加载。

当我写的分布式计算环境的用户基于尝试执行动态实例化动态实例化作业的作业(2级反射实例化)时,出现了这个问题。基本上,像这个伪调用列表:

reflectivelyCreate(job)
job.reflectivelyCreate(job2)
job2.instantiateActorSystem()
<fail>

如果我按以下方式运行完全相同的代码:

reflectivelyCreate(job2)
job2.instantiateActorSystem()
<success>

一切正常。

我的问题是,是否在Java中幕后发生了一些有状态的类加载器相关魔术,以至于Akka对其状态的假设是不正确的。我发现的类似问题(Akka ActorSystem creation issue)似乎与线程/ scala repl调用有关,但我的代码是单线程的,并且在上面的成功和失败情况下都以相同的方式调用。到目前为止,只有在调用堆栈深度不同的情况下才会发生有问题的调用。

我很感激来自akka大师的任何意见!

1 个答案:

答案 0 :(得分:1)

如果其他人偶然发现了这一点;我的问题是我在同一个进程中使用scala解释器,也可能使用Akka。其他多类加载器方案可能会出现相同的问题。以下是我案例的修复:

  • 使用private static ClassLoader ourClassLoader = CmdLineMain.class.getClassLoader();
  • 在程序初始化时将我喜欢的类加载器(加载akka库的类加载器)保存在静态字段中
  • 使用scala解释器(显然用它喜欢的类替换了类加载器)后,调用Thread.currentThread().setContextClassLoader(ourClassLoader);

我的程序是单线程的,但是肯定有其他方法可以解决问题,这样每个线程都可以维护自己的加载器。这超出了这篇文章的范围;)