2012-04-30 23 views
19

私はクライアントとサーバーを作成し、クライアント側でクラスを追加してシリアル化しました。次に、単にハードドライブのクライアントのフォルダに移動し、サーバーの対応する場所はそれぞれclassname.classclassname.javaです。java.io.InvalidClassException:ローカルクラスが互換性がありません:

それは私自身のラップトップでよく働いたが、私は他のシステム上で私の仕事を続けたいと思ったとき、私はプロジェクトのフォルダを開いたときに、クライアントがサーバーに接続しようとした後、次のエラーが表示されます。

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の古いバージョンでプログラムを実行したからですか?

EDIT

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; 


} 

答えて

27

クラスが明示的にそれが自動生成されるコードでprivate static final long serialVersionUIDを定義していない、別のマシンが同じIDを生成するという保証はありません場合は、それはまさに何が起こったかのようです。 また、(クラスの異なるバージョンを使用して)クラスが異なる場合は、自動生成されたserialVersionUIDも異なるでしょう。 Serializableインタフェースのdocsから

直列化可能クラスが明示的にserialVersionUIDを宣言していない場合は説明したように、その後、直列化ランタイムが、クラスのさまざまな側面に基づいて、そのクラスのデフォルトserialVersionUID値を計算しますJava(TM)オブジェクト直列化仕様書に記載されている。ただし、serialVersionUIDの計算は、コンパイラの実装によって異なることがあるクラスの詳細に非常に敏感であり、したがってデシリアライズ時に予期しない結果となる可能性があるので、を強くお勧めします。したがって、さまざまなJavaコンパイラ実装間で一貫したserialVersionUID値を保証するには、直列化可能クラスで明示的にserialVersionUIDの値を宣言する必要があります。可能であれば、明示的なserialVersionUID宣言ではprivate修飾子を使用することを強くお勧めします。この宣言はすぐに宣言するクラスにのみ適用されます。serialVersionUIDフィールドは継承されたメンバーとしては有用ではありません。配列クラスは明示的にserialVersionUIDを宣言することができないため、常にデフォルトの計算値を持ちますが、serialVersionUID値の一致要件は配列クラスに対しては放棄されます。

あなたはクラス定義でserialVersionUIDを定義する必要があり、例えば:

class MyClass implements Serializable { 
    private static final long serialVersionUID = 6529685098267757690L; 
    ... 
+0

定義でserialVersionUIDを調整する方法は? – lonesome

+0

まだ同じエラーが発生します – lonesome

+0

これは奇妙です。私は両方の側がクラスの最新バージョンを使用していることを再確認します。 – trutheality

0

私はあなたが、クライアントとサーバー上の同じクラスの異なるバージョンを使用しているため、この問題が発生したと考えています。 異なるデータフィールドまたはメソッドにすることができます

0

Javaでのシリアル化は、長期間の永続性またはトランスポート形式ではありません。クラスのバイトコードとJVMのわずかな違いで、あなたのデータはもはや読み込みができません。

+2

私は永続性の程度に同意することができますが、Javaシリアル化をトランスポート形式として使用することには何も問題ありません。 'serialVersionUID'のようなJavaの直列化の概念を知らないのはあまりにも脆弱です。 –

+0

それでも壊れやすいです。 –

+0

本当にそうではありません。たぶん、さまざまな色の眼鏡で「Javaシリアル化」の世界が見えてくるかもしれません。それだけでなく、RMIを使うときの唯一のオプションです。また、後で編集された「プロジェクトマネージャスキンニング」についていくつかコメントしていたことがわかりました。 –

0

例外メッセージでは、クラスのメタデータも含めてクラスのバージョンが明確に表示されています(例:XStreamはすばやく簡単に使用できます)時間とともに変化してきました。つまり、直列化中のクラス構造は、逆直列化中は同じではありません。これはおそらく "進んでいる"ものです。

関連する問題