2016-02-10 28 views
0

我正在尝试设置一个Akka系统,其中反序列化错误触发了一个协议,其中缺少类别被交换。我使用一个自定义的de/serializer来达到这个目的,一旦它捕获到一个与缺少的类有关的异常,就会向应用程序actor发送一个特定的消息。在Akka中的反序列化和类加载 - NoClassDefFoundError

简而言之,远程系统B将一个对象发送给系统A;如果在反序列化期间系统A得到ClassNotFoundErrorNoClassDefFoundError,则系统A向系统B请求未定义类的字节码。当A收到来自B的响应(这是一对classname加上一个Array [Byte]类型的对象),那么它可以注册该类,以便下一次系统B将该对象发送给系统A,A可以对它进行反序列化正确。

现在,有两种方法

1)系统B也发送有关的所有所请求的类

2)系统B只发送针对所请求的类的字节代码(没有它的依赖)

的类

现在,让我们集中在方法2和考虑以下情形

  • 1)B === OBJ:X ==> A(B发送类X至A的对象)
  • 2)让我们假设X取决于Y,Z
  • 3)乙< ==== X?==== A(A询问类X到B)
  • 4)乙==== = X ====> B(B将类X提供给A;甲寄存器类X)
  • 5)乙=== OBJ:X ==> A(A获得误差由于缺少依赖Y)
  • 6)乙< ====ý====甲
  • 7)乙=====ý====> A(A寄存器类Y)
  • 8)乙=== OBJ:X ==>甲
  • 9)乙< ==== Z ==== A
  • 10)B ===== Z ====> A(A寄存器类Z)
  • 10)B === obj:X ==> A(OK,最后A可以反序列化X类对象)

我认为这样的协议应该工作,但在实践中,我得到的步骤5-7的循环,由于以下

NoClassDefFoundError的:Lexamples/DemoDecentralizedAkkaPlatformCmdLineMain2 $ AggregateProgram $$ anonfun $主$ 3 $$ anonfun $应用$ 5;

我去注册以下类:examples.DemoDecentralizedAkkaPlatformCmdLineMain2 $ AggregateProgram $$ anonfun $主$ 3 $$ anonfun $ $申请5

但我不断收到的NoClassDefFoundError。

请注意,我将最初的“L”和尾随的“;”从类名称,以及用“。”替换“/”。否则,我会在系统B上发生错误。

对于这样复杂的问题表述,我很抱歉。

回答

0

从抽象的概念:

一旦你得到了“NoClassDefFound Y”加载类“X”的错误,你有没有保证扔掉“X”,和负载的类加载器“A”在一个新的类loader,其中包含'Y'的字节代码。如果一个类被加载,但是加载失败,那么JVM会记住这个错误并重新抛出它。至少对于某些类初始化错误。所以你需要在新的类加载器中尝试重新加载。

诚实推荐: 如果您尝试创建可靠的分布式系统,请避免依赖确切的字节共享字节码或发送字节码。它会使系统非常脆弱。最好奇怪的类加载器错误,方法没有发现错误,序列化错误。在最糟糕的情况下,系统会运行看不见的,意外的代码:就像您部署了一个新版本,但它从一个仍在运行的其他实例中加载旧代码。 使用一些固体,字节码独立序列化。选择其中的一种序列化格式。 Akka带来了包括protobuf serializer。包括另一个很容易。