出于重用原因,我将当前的序列化/反序列化服务包装在一个抽象的泛型类中,该类在整个项目的共享JAR中编译。我需要将对象序列化为String
可以扩展类,并且可以在其他JAR / WAR中为其指定类型(是的,这是一个Web应用程序)。
当我在同一个WAR中进行第一次反序列化测试时,一切正常,但是现在我将抽象类移动到另一个JAR中,我在反序列化时得到一个ClassNotFoundError。
基类的结构如下:
public abstract class ConverterBase<T extends Serializable> {
public final Object getAsObject(String str) {
//Use java.io serialization services from the base64 representation
try {
ByteArrayInputStream ba = new ByteArrayInputStream(decoder
.decodeBuffer(str));
try {
ObjectInputStream is = new ObjectInputStream(ba);
try {
Object ret = is.readObject();
return ret;
} finally {
is.close();
}
} finally {
ba.close();
}
} catch (Throwable ex) {
return null;
}
}
public final String getAsString(Object obj) {
//simply do the opposite
}
}
它的结构是这样的,以便允许将来的更改影响所有子类(即避免使用base64,效率更高......)。目前,java.io
解决方案是临时实施。
然后我在同一个WAR中有以下内容:
public class MyPojo implements Serializable {
//Stuff
}
public final class MyPojoConverter extends ConverterBase<MyPojo> { }
扩展此类的类与抽象类位于不同的存档中,并且在该WAR的类型上专用。
我该怎么做才能避免这个错误?
谢谢
答案 0 :(得分:1)
如果要将数据存储为String,我将使用XML或JSon使用XStream等工具序列化对象。这些工具对包,类名,父类,接口或方法更改的更改不敏感。
答案 1 :(得分:0)
ObjectInputStream必须能够访问序列化对象中使用的所有类。
通常,如果创建线程的代码(例如其类加载器)可以加载流中提到的每个类,那就足够了。确保是这种情况。 (我不确定您的应用程序容器中的类加载器结构。如果您提供有关此的更多信息,也许其他人可以提供帮助。)
对于更复杂的情况,您可以创建一个子类并覆盖resolveClass
。
答案 2 :(得分:0)
这可能是一个类加载问题(是的,当然)。 如果我说得对,那么问题就发生在你的WAR中,即JSP或servlet。 请提供您的堆栈跟踪,我不确定,找不到哪个类。