我正在實現一個功能,要求在JVM的多個實例(通過網絡)之間傳遞動態生成的類型(以二進制表示形式,使用Kryo序列化)。爲了正確地解析哪些類型被加載,哪些不是我使用的定製系統類加載器(作爲java -Djava.system.class.loader
參數傳遞),由其他動態創建的類加載器用作父類。這個自定義的系統類加載器知道它的子代,並且如果它找不到類,可以詢問這些派生類加載器是否擁有它(這與類加載器的標準層次結構相反)。自定義系統類加載器不被所有類使用
這些動態生成的類型在不同的JVM之間傳輸和加載得很好。當我嘗試反序列化某種類型的實例(從光盤加載對應的類並且對於所有JMV是相同的)並引用其中一個動態生成的類型時,問題就出現了 - ClassNotFoundException由Kryo的實例重新定義,該實例試圖readClass
按動態生成類型的名稱。
裏面方法readClass
那裏Class.forName
一個電話,這反過來不使用指定的自定義類加載器(即知道所有動態生成的類型),而是使用sun.misc.Launcher $ AppClassLoader實例。
是否可以指定一個定製的系統範圍的類加載器,以便所有類都加載它以避免所描述的問題?
更新
進一步分析發現,ClassLoader.getSystemClassLoader()
實際返回指定的自定義系統類加載器。幸運的是,Kryo庫支持設置自定義類加載器,專門用於在反序列化時加載類。這兩個事實構成了解決所述問題的基礎。
當然......我只是希望JVM能夠分析加載java.system.class.loader本身所需的最小需要的類,然後用它加載所有剩下的類。感謝您的建議。 – 01es 2012-04-20 13:07:30
我相信它假設你不會改變最小的一組類,所以他們不需要重新加載。 – 2012-04-20 13:25:44
它們不需要重新加載,但它們的實例可能會開始引用動態加載的多態兼容類型的實例,結果將無法使用在序列化/反序列化過程中加載的默認類來查找它們。是否有關於類加載,本地Instrumentation代理和自定義AppClassLoader實現的權威性參考資料? JVM規範?謝謝。 – 01es 2012-04-20 14:25:58