java.io.WriteAbortedException:写入中止; java.io.NotSerializableException
Posted
技术标签:
【中文标题】java.io.WriteAbortedException:写入中止; java.io.NotSerializableException【英文标题】:java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException 【发布时间】:2011-01-18 16:03:38 【问题描述】: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)
【问题讨论】:
【参考方案1】:您需要使bean.ProjectAreaBean
可序列化。
【讨论】:
在readObject
而不是writeObject
上会引发此错误有点奇怪。数据是否可以由具有可序列化类版本的另一个版本的程序写入?在这种情况下,请确保您的所有代码都具有相同的 jar 文件。并且不要更新您的可序列化类。
你好,谢谢你的帮助,但我不知道如何序列化这个类【参考方案2】:
只需执行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
值,该值基本上是基于所有字段计算的哈希值。
另见:
JSF managed bean causing java.io.NotSerializableException during Tomcat deployment Injecting non-serializable application scoped bean as managed property of serializable session scoped bean in a cluster What is a serialVersionUID and why should I use it?标记不可序列化的字段transient
如果您的Serializable
类又包含引用另一个类的实例的字段/属性,则绝对不能将其设为Serializable
(通常,这些代表资源,例如InputStream
、Connection
等) ,那么您需要将其标记为transient
。这样在类的序列化过程中将被跳过。
private transient SomeObject thisWillNotBeSerialized;
您需要了解,在反序列化后,该字段将始终变为null
。请注意,在反序列化期间不调用类的构造函数和初始化块。如果您想对序列化和反序列化进行更细粒度的控制,请覆盖 readObject()
和 writeObject()
方法。您可以在以下链接中找到具体示例:
为什么要序列化?
至于为什么您需要担心序列化,这是因为大多数 Java servlet 容器(如 Tomcat)需要类来实现 Serializable
,只要这些类的实例被存储为HttpSession
。这是因为HttpSession
可能需要保存在本地磁盘文件系统上,甚至在 servlet 容器需要关闭/重新启动或放置在必须同步会话的服务器集群中时通过网络传输。
为了能够将 Java 对象保存在本地磁盘文件系统上或通过网络传输它们,必须首先将它们转换为字节流(基本上:byte[]
或 InputStream
),即只有当对象后面的类实现Serializable
时才有可能。 Serializable
接口本身并没有真正做任何事情,它只是一个marker interface。后面的代码只是对会话属性进行instanceof Serializable
检查以采取相应的行动。
另见:
java.io.Serializable
javadoc
Java Object Serialization Specification
Java Tutorials - Essential Classes - Basic I/O - Object Streams
【讨论】:
以上是关于java.io.WriteAbortedException:写入中止; java.io.NotSerializableException的主要内容,如果未能解决你的问题,请参考以下文章