这周,我们再次遇到了这个错误。但我找到了根本原因。ObjectInputStream使用的类加载器是高度依赖上下文的(有人会说不 确定性
)。这是Sun文档的相关部分(摘自ObjectInputStream#resolveClass(ObjectStreamClass)):
[class loader]的确定如下:如果当前线程的堆栈上有一个方法的声明类是由用户定义的class
loader定义的(并且不是为实现反射调用而生成的),则它是class
loader对应于最接近当前执行帧的这种方法;否则为null。如果此调用导致ClassNotFoundException且传递的ObjectStreamClass实例的名称是原始类型或void的Java语言关键字,则将返回表示该原始类型或void的Class对象(例如,名称为“
int”的ObjectStreamClass
”将解析为Integer.TYPE)。否则,ClassNotFoundException将被抛出给该方法的调用者。
在我们的应用程序中,我们有一个Eclipse插件B,它依赖于仅实用程序的插件A。我们正在反序列化其类在B中的对象,但是反序列化是在A中启动的(在那里创建ObjectInputStream),这就是问题所在。反序列化很少(即取决于文档所说的调用堆栈)选择了错误的类加载器(一个不能加载B类的加载器)。为了解决此问题,我们将适当的加载程序从顶级反序列化调用程序(在B中)传递给A中的Utility方法。此方法现在使用如下的自定义ObjectInputStream(请注意,自由变量“
loader”):
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file)) { @SuppressWarnings("rawtypes") @Override protected Class resolveClass(ObjectStreamClass objectStreamClass) throws IOException, ClassNotFoundException { return Class.forName(objectStreamClass.getName(), true, loader); } };
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)