簡體   English   中英

如果我更改了 java 類的包。 舊序列化版本的反序列化仍然有效嗎?

[英]If i changed the package of a java class. Will the deserialization from the old serialized version still work?

我在我的 java 項目中使用 aerospike 作為緩存。 我更改了我的緩存對象之一的包。 我在一台機器上部署了新代碼。 獲取序列化異常,因為緩存中存在舊的緩存對象。

我希望舊代碼在某些機器上運行,而在某些機器上運行新代碼,並且兩者都應該能夠在 aerospike 緩存中獲取/放置對象。

有沒有辦法實現這一目標? 為什么我會收到此異常。

類所屬的包是該類標識的基本部分,正如包名稱是類的完全限定名稱的一部分所反映的那樣。 出於所有實際意圖和目的,更改為類分配的包會刪除原始類並將其替換為完全不同的類。

特別是,如果您通過 Java 序列化序列化名為“my.package.MyClass”的類的實例,那么成功反序列化結果總是會產生名為“my.package.MyClass”的類的實例。 如果不能加載這樣的類,或者如果加載的類的序列化版本與已序列化的類的版本不匹配,則反序列化將失敗。

如果您保留舊類和新類,那么您也許可以在新版本的應用程序中修補反序列化問題。 只需為舊類的對象做好准備,並在反序列化后立即將它們轉換為新類的實例。 但是如果你想讓新版本的應用程序和舊版本的應用程序一起玩,那么你也必須在新版本序列化受影響類的對象時進行相反的操作,否則只會導致舊應用程序出現反序列化錯誤。 在這一點上,您應該考慮更改包名稱是否真的那么重要。

總的來說,Java 序列化不太適合對象存儲。 它主要針對對象通信 您可能會考慮切換到基於 XML、JSON 或 YAML 的序列化格式,至少您可以在緩存和使用者之間切換。 這樣的更改當然會與您的應用程序的舊版本不兼容,但顯然,您已經執行的包更改也是如此。

通常,序列化算法執行以下操作:

  • 它寫出與實例關聯的類的元數據。
  • 它遞歸地寫出超類的描述,直到找到java.lang.object
  • 一旦完成寫入元數據信息,它就會從與實例關聯的實際數據開始。 但這一次,它從最頂層的超類開始。
  • 它遞歸地寫入與實例關聯的數據,從最少的超類開始到派生最多的類。

在反序列化期間,它將嘗試重新實例化該類,但由於包名稱已更改,因此無法找到元數據中指定的類並失敗。

查看以下工具可能是值得的: jDeserialize 它不會實例化流中描述的任何類; 相反,它構建了類型、實例和值的中間表示。 因此,它可以分析流而無需訪問生成它們的類代碼。

您可以將 ObjectInputStream 子類化並使用它來攔截 readClassDescriptor,如果被反序列化的類的包與您的不同,您可以更改它。 但是,如果被反序列化的類然后包含需要反序列化的其他類,則情況會變得更加復雜。

public class MyObjectInputStream extends ObjectInputStream {

    public MyObjectInputStream(InputStream in) throws IOException {
        super(in);
    }

    @Override
    protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException {
        ObjectStreamClass resultClassDescriptor = super.readClassDescriptor();
        String className = resultClassDescriptor.getName();
        if (className.equals("my.old.pacakgename.MyClass")) {
            return ObjectStreamClass.lookup(MyClass.class);
        }
        return resultClassDescriptor;
    }
}

要使用這個

ObjectInputStream ois = new MyObjectInputStream(stream);
MyClass myObject = (MyClass) ois.readObject();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM