java.io.WriteAbortedException:写入已中止; java.io.NotSerializableException

时间:2010-02-19 06:46:48

标签: java-ee tomcat java-io catalina 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)

2 个答案:

答案 0 :(得分:44)

只需实施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()方法。您可以在以下链接中找到具体示例:


为什么要序列化?

至于为什么你需要担心序列化,这是因为大多数Java servlet容器如Tomcat都要求类在这些类的实例存储为属性时实现SerializableHttpSession。这是因为当servlet容器需要关闭/重启或者被放置在必须同步会话的服务器集群中时,HttpSession可能需要保存在本地磁盘文件系统上,甚至可以通过网络传输。

为了能够在本地磁盘文件系统上保存Java对象或通过网络传输它们,必须先将它们转换为字节流(基本上是:byte[]InputStream )并且只有在对象后面的类实现Serializable时才可能。 Serializable接口本身并没有真正做任何事情,它只是一个marker interface。后面的代码仅对会话属性进行instanceof Serializable检查以相应地执行操作。

另见:

答案 1 :(得分:3)

您需要bean.ProjectAreaBean可序列化。