3

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

这些动态生成的类型可以完美地在不同的 JVM 之间传输和加载。当我尝试反序列化引用动态生成的类型之一的某种类型的实例(从磁盘加载相应的类并且对于所有 JMV 都是相同的)时,就会出现问题——ClassNotFoundException 由 Kryo 的实例引发,它试图readClass按动态生成的类型的名称。

在方法内部readClass调用Class.forName,它不使用指定的自定义类加载器(知道所有动态生成的类型),而是使用 sun.misc.Launcher$AppClassLoader 实例。

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


更新

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

4

1 回答 1

4

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

解决这个问题的一种方法是创建一个本地检测代理。这是在加载任何类之前加载的。

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

于 2012-04-20T11:18:47.013 回答