2016-02-10 54 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。包括另一個很容易。