我正在实现一个功能,该功能需要在多个 JVM 实例(通过网络)之间传递动态生成的类型(以二进制表示,用 Kryo 序列化)。为了正确解决加载哪些类型以及不加载哪些类型,我使用了自定义系统类加载器(作为 java-Djava.system.class.loader
参数传递),其他动态创建的类加载器将其用作父类。这个自定义系统类加载器知道它的子类,如果它找不到一个类,可以询问这些派生类加载器是否有它(这与类加载器的标准层次结构相反)。
这些动态生成的类型可以完美地在不同的 JVM 之间传输和加载。当我尝试反序列化引用动态生成的类型之一的某种类型的实例(从磁盘加载相应的类并且对于所有 JMV 都是相同的)时,就会出现问题——ClassNotFoundException 由 Kryo 的实例引发,它试图readClass
按动态生成的类型的名称。
在方法内部readClass
调用Class.forName
,它不使用指定的自定义类加载器(知道所有动态生成的类型),而是使用 sun.misc.Launcher$AppClassLoader 实例。
是否可以指定自定义系统范围的类加载器,以便所有类都加载它以避免所描述的问题?
更新
进一步分析发现,ClassLoader.getSystemClassLoader()
实际上返回的是指定的自定义系统类加载器。幸运的是,Kryo 库支持设置自定义类加载器,专门用于在反序列化时加载类。这两个事实构成了解决上述问题的基础。