web-dev-qa-db-ja.com

java.io.WriteAbortedException:書き込みが中止されました。 Java.io.NotSerializableException

Tomcatでこの種のエラーが発生する原因は何ですか?

SEVERE: Exception loading sessions from persistent storage
Java.io.WriteAbortedException: writing aborted; Java.io.NotSerializableException:
   bean.ProjectAreaBean
 at Java.io.ObjectInputStream.readObject0(ObjectInputStream.Java:1333)
 at Java.io.ObjectInputStream.readObject(ObjectInputStream.Java:351)
 at Java.util.ArrayList.readObject(ArrayList.Java:593)
 at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:39)
 at Sun.reflect.DelegatingMethodAccessorImpl.invoke(
    DelegatingMethodAccessorImpl.Java:25)
21
deven

Serializableを実装するだけです

次のような NotSerializableException を取得している場合、

_Java.io.NotSerializableException: bean.ProjectAreaBean
_

次に、それは単に、例外メッセージの完全修飾名(この場合は_bean.ProjectAreaBean_)で識別されるクラスが Serializable インターフェースを実装しないことを意味しますが、コードビハインド。修正は比較的簡単で、クラスにSerializableインターフェースを実装させるだけです。

_package bean;

import Java.io.Serializable;

public class ProjectAreaBean implements Serializable {
    private static final long serialVersionUID = 1L;

    // ...
}
_

serialVersionUIDフィールドは必須ではありませんが、クラスの異なるバージョンとそのインスタンスのシリアル化された表現の間のバイナリ互換性を維持するため、強くお勧めします。したがって、後でクラスに新しいシリアル化可能なフィールドを追加するときは、クラスの古いバージョンのインスタンスの逆シリアル化中に問題が発生しないように、serialVersionUIDフィールドを変更する必要があります(通常は1だけ増やすだけで十分です)。 EclipseなどのIDEには、基本的にすべてのフィールドに基づいて計算されたハッシュであるserialVersionUID値を(再)生成するオプションもあります。

以下も参照してください。


シリアル化できないフィールドにマークを付けるtransient

Serializableクラスに、絶対にSerializableにすることができない別のクラスのインスタンスを参照するフィールド/プロパティが含まれている場合(通常、これらはInputStreamConnectionなどのリソースを表します)、transientをマークする必要があります。これにより、クラスのシリアル化中にスキップされます。

_private transient SomeObject thisWillNotBeSerialized;
_

逆シリアル化後、このフィールドは常にnullになることを理解する必要があります。クラスのコンストラクターと初期化ブロックは、逆シリアル化中に呼び出されないことに注意してください。シリアライゼーションとデシリアライゼーションをより細かく制御したい場合は、readObject()メソッドとwriteObject()メソッドをオーバーライドします。以下のリンクに具体的な例があります。


なぜシリアライズなのか?

whyについては、シリアル化について心配する必要があります。これは、TomcatのようなほとんどのJavaサーブレットコンテナは、それらのインスタンスが常にSerializableを実装するクラスを必要とするためですクラスは HttpSession の属性として保存されます。これは、サーブレットコンテナーをシャットダウン/再起動する必要がある場合、またはネットワーク経由で転送する必要がある場合に、HttpSessionをローカルディスクファイルシステムに保存する必要があるためです。セッションを同期する必要があるサーバーのクラスターに配置されている。

Javaオブジェクトをローカルディスクファイルシステムに保存したり、ネットワーク経由で転送したりできるようにするには、まずバイトストリームに変換する必要があります(基本的には_byte[]_またはInputStream)およびオブジェクトの背後にあるクラスがSerializableを実装している場合にのみ可能です。Serializableインターフェース自体は実際には何もせず、単に マーカーインターフェース 。背後のコードは、セッション属性に対して_instanceof Serializable_チェックを実行するだけで、それに応じて動作します。

以下も参照してください。

50
BalusC

bean.ProjectAreaBeanをシリアライズ可能にする必要があります。

3
Thilo