2011-06-10 106 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。 請提供您的堆棧跟蹤,我不確定哪個類別無法找到。