Foo
過去にs1、3、および17があったクラスがあり、3つのバージョンすべてをインスタンスserialVersionUID
に読み取ることができる必要があるとします。Foo
それ、どうやったら出来るの?
特に、どのバージョンがバイトストリームに保存されたかを知る必要があるので、データ移行を行うことができます。serialVersionUID
にアクセスするにはどうすればよいreadObject()
ですか?それとももう手遅れですか?
Foo
過去にs1、3、および17があったクラスがあり、3つのバージョンすべてをインスタンスserialVersionUID
に読み取ることができる必要があるとします。Foo
それ、どうやったら出来るの?
特に、どのバージョンがバイトストリームに保存されたかを知る必要があるので、データ移行を行うことができます。serialVersionUID
にアクセスするにはどうすればよいreadObject()
ですか?それとももう手遅れですか?
簡単ではありませんが、可能です。クラスの履歴バージョンごとに、古いバージョンのデータ モデル クラスをロードする個別のクラスローダーを作成する必要があります。次に、いくつかが収まるまで、各クラスローダーでファイルを読み取ってみる必要があります。ObjectInputStream
スレッドコンテキストから現在のクラスローダーを使用していると思います。詳細が必要な場合は、お気軽にお問い合わせください。
後で追加: どのクラスローダが によって使用されるかを指定するのはそれほど簡単ではないようObjectInputStream
です。ここではおそらく追加の調査が必要です。
後で別の追加:おそらくresolveClass(ObjectStreamClass)
メソッドをオーバーライドしObjectInputStream
て、適切なクラスローダーを使用できます。
オブジェクトの異なるバージョンを逆シリアル化するには、異なるクラスローダーを使用します。その後、以前のバージョンに基づいて共通 (おそらく最新) インスタンスの内部状態を手動で初期化する必要があります (そのためのコンバーターを作成する必要があります)。
クラスローダーのパスが完全に異なることを確認してください。スーパー クラスローダーがクラスをロードできる場合は、ロードします。したがって、すべてのクラスローダーは互いに完全に分離する必要があります (どちらも他のクラスローダーのスーパーであってはなりません)。
前者はserialVersionUID
、逆シリアル化中にエラーをキャッチすることで取得できます。
try {
// deserialize here...
} catch (final java.io.InvalidClassException e) {
System.out.println(e.getMessage());
// The message string contains the former uid.
// Message: local class incompatible: stream classdesc serialVersionUID = OLD_UID_HERE, local class serialVersionUID = NEW_UID_HERE
}