クライアントとサーバーを作成し、シリアル化のためにクライアント側にクラスを追加し、ハードドライブのクライアントのフォルダーに移動して、サーバーに対応する場所にコピーペーストします。両方ともclassname.class
およびclassname.Java
それぞれ。
自分のラップトップではうまく機能しましたが、他のシステムで作業を続けたい場合、プロジェクトフォルダーを開いたときに、クライアントがサーバーに接続しようとすると、次のエラーが表示されます。
Exception in thread "main" Java.io.InvalidClassException: projectname.clasname; local class incompatible: stream classdesc serialVersionUID = -6009442170907349114, local class serialVersionUID = 6529685098267757690
at Java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.Java:562)
at Java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.Java:1582)
at Java.io.ObjectInputStream.readClassDesc(ObjectInputStream.Java:1495)
at Java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.Java:1731)
at Java.io.ObjectInputStream.readObject0(ObjectInputStream.Java:1328)
at Java.io.ObjectInputStream.readObject(ObjectInputStream.Java:350)
何が起こっている?古いバージョンのIDEでプログラムを実行したためですか?
import Java.io.Serializable;
import Java.net.URL;
public class KeyAdr implements Serializable {
private static final long serialVersionUID = 6529685098267757690L;
public URL adr;
public String key;
}
クラスがコードでprivate static final long serialVersionUID
を明示的に定義しない場合、クラスは自動生成され、異なるマシンが同じIDを生成する保証はありません。それがまさに起こったことのように見えます。また、クラスが何らかの方法で異なる場合(クラスの異なるバージョンを使用)、自動生成されたserialVersionUID
sも異なります。
Serializable
インターフェイスの docs から:
シリアライズ可能クラスが
serialVersionUID
を明示的に宣言しない場合、シリアライゼーションランタイムは、Java(TM)Object Serialization Specificationで説明されているように、クラスのさまざまな側面に基づいて、そのクラスのデフォルトserialVersionUID
値を計算します。ただし、デフォルトのserialVersionUID
計算は、コンパイラーの実装によって異なる可能性のあるクラスの詳細に非常に敏感であり、したがって、逆シリアル化中に予期しないserialVersionUID
値になるため、すべてのシリアライズ可能クラスが明示的にInvalidClassExceptions
値を宣言することは強く推奨です。したがって、異なるJavaコンパイラー実装間で一貫したserialVersionUID
値を保証するには、シリアライズ可能なクラスが明示的なserialVersionUID
値を宣言する必要があります。また、明示的なserialVersionUID
宣言は可能な限りprivate
修飾子を使用することを強くお勧めしますこのような宣言は、すぐに宣言するクラスにのみ適用されます-serialVersionUID
フィールドは継承されたメンバーとしては有用ではありません。配列クラスは明示的なserialVersionUID
を宣言できないため、常にデフォルトの計算値を持ちますが、配列クラスではserialVersionUID
値と一致する必要はありません。
クラス定義でserialVersionUID
を定義する必要があります。例:
class MyClass implements Serializable {
private static final long serialVersionUID = 6529685098267757690L;
...
起こりうることの1つ:
したがって、バージョンXのコンパイル時に、JVMは最初のシリアルID(バージョンX用)を生成し、他のバージョンY(別のシリアルID)と同じことを行います。
プログラムがデータを逆シリアル化しようとすると、2つのクラスが同じシリアルIDを持たず、2つのシリアル化されたオブジェクトが同じクラス形式に対応することをプログラムが保証しないため、できません。
その間にコンストラクタを変更したと仮定すると、これはあなたにとって理にかなっているはずです。
例外メッセージは、クラスメタデータも含むクラスバージョンが時間とともに変化したことを明確に示しています。つまり、シリアル化中のクラス構造は、逆シリアル化中と同じではありません。これがおそらく「進行中」です。
これは、クライアントとサーバーで同じクラスの異なるバージョンを使用しているために発生すると考えています。異なるデータフィールドまたはメソッドにすることができます
Oc4jを使用してearを展開している場合。
プロジェクトにdeploy.home =の正しいパスを設定してください。
Common.propertiesファイルでdeploy.homeを見つけることができます
Oc4jは、サーバークラスとクライアントクラスが同じserialVersionUIDを持つように、耳に新しく作成されたクラスをリロードする必要があります
Javaでのシリアル化は、長期の永続性またはトランスポート形式を意味するものではありません。これには脆弱すぎます。タスクのJSONデータバインディング( XStream は高速で使いやすく、多数の代替手段があります)