2011-06-10 109 views
0

由于重用的原因,我将当前的序列化/反序列化服务封装在抽象的泛型类中,该泛型类在整个项目的共享JAR中编译。我需要序列化对象到StringJava反序列化问题

该类可以扩展,并且可以在其他JAR/WARs中指定类型(是的,这是一个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> { } 

扩展这个人是比抽象类不同的归档,并专门上的类型的战争类。

我该怎么做才能避免该错误?

谢谢

+0

搬进另一个包装或另一个罐子? – PeterMmm 2011-06-10 12:34:21

+0

打包战争时,为什么不包含jar文件和缺少的类?通常它只需要在lib子文件夹中(不知道是否需要在Class-Path标记中的战争Manifest中引用它,但我不这么认为) – 2011-06-10 12:35:08

+0

@peter:另一个JAR - @angel:JAR存储在磁盘上的通用库中 – 2011-06-10 13:12:21

回答

0

ObjectInputStream必须能够访问在序列化对象中使用的所有类。

通常,创建线程的代码(例如其类加载器)可以加载流中提到的每个类就足够了。确保这是事实。 (我不确定你的应用程序容器中的类加载器结构,如果你提供了更多关于这个的信息,其他人可以提供帮助。)

对于更复杂的情况,你可以创建一个子类并覆盖resolveClass

+0

这是一个由多个WAR和库JAR制作的Tomcat Web应用程序。我不知道是否有人修改了类加载器,因为我没有关于这个的文档 – 2011-06-10 12:53:10

1

如果你想存储的数据为字符串,我会用XML或JSON与像XStream的一个工具,你的序列化对象。这些工具对包,类名,父类,接口或方法更改中的更改不敏感。

+0

XML是详细的。其实base64也是。但我说,这只是第一次执行 – 2011-06-10 12:51:52

+1

你可以发现ObjectStream也是详细的。一个Integer需要81个字节(两个需要91个字节)如果文本格式太大,可以将它压缩得相当好。 – 2011-06-10 13:11:07

0

这可能是一个类加载问题(是的,当然)。 如果我对你有所了解,问题就发生在你的WAR内部,即JSP或servlet。 请提供您的堆栈跟踪,我不确定哪个类别无法找到。