2012-04-20 86 views
3

我正在实现一个功能,要求在JVM的多个实例(通过网络)之间传递动态生成的类型(以二进制表示形式,使用Kryo序列化)。为了正确地解析哪些类型被加载,哪些不是我使用的定制系统类加载器(作为java -Djava.system.class.loader参数传递),由其他动态创建的类加载器用作父类。这个自定义的系统类加载器知道它的子代,并且如果它找不到类,可以询问这些派生类加载器是否拥有它(这与类加载器的标准层次结构相反)。自定义系统类加载器不被所有类使用

这些动态生成的类型在不同的JVM之间传输和加载得很好。当我尝试反序列化某种类型的实例(从光盘加载对应的类并且对于所有JMV是相同的)并引用其中一个动态生成的类型时,问题就出现了 - ClassNotFoundException由Kryo的实例重新定义,该实例试图readClass按动态生成类型的名称。

里面方法readClass那里Class.forName一个电话,这反过来不使用指定的自定义类加载器(即知道所有动态生成的类型),而是使用sun.misc.Launcher $ AppClassLoader实例。

是否可以指定一个定制的系统范围的类加载器,以便所有类都加载它以避免所描述的问题?


更新

进一步分析发现,ClassLoader.getSystemClassLoader()实际返回指定的自定义系统类加载器。幸运的是,Kryo库支持设置自定义类加载器,专门用于在反序列化时加载类。这两个事实构成了解决所述问题的基础。

回答

4

如果所有类都必须使用该类加载器来加载,您将如何加载自定义类加载器?

解决此问题的一种方法是创建本机仪表代理。这是在加载任何类之前加载的。

解决它的另一种方法是编译自己的AppClassLoader版本并将其前缀到引导类路径或将其添加到libs/endorsed目录。

+0

当然......我只是希望JVM能够分析加载java.system.class.loader本身所需的最小需要的类,然后用它加载所有剩下的类。感谢您的建议。 – 01es 2012-04-20 13:07:30

+0

我相信它假设你不会改变最小的一组类,所以他们不需要重新加载。 – 2012-04-20 13:25:44

+0

它们不需要重新加载,但它们的实例可能会开始引用动态加载的多态兼容类型的实例,结果将无法使用在序列化/反序列化过程中加载的默认类来查找它们。是否有关于类加载,本地Instrumentation代理和自定义AppClassLoader实现的权威性参考资料? JVM规范?谢谢。 – 01es 2012-04-20 14:25:58

相关问题