我正在实现一个功能,要求在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