java.io.WriteAbortedException:写入已中止; java.io.NotSerializableException [英] java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException
问题描述
在Tomcat中导致此类错误的原因是什么?
What causes this kind of error in 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)
推荐答案
只需实现 Serializable
如果你得到一个 NotSerializableException
如下所示,
Just implement Serializable
If you're getting a NotSerializableException
like follows,
java.io.NotSerializableException: bean.ProjectAreaBean
然后它只是意味着类a由异常消息中的完全限定名称标识的(在您的情况下为 bean.ProjectAreaBean
)未实现 可序列化
界面,但预期由背后的代码。修复它相对简单,只需让类实现 Serializable
接口。
then it simply means that the class as identified by the fully qualified name in the exception message (which is bean.ProjectAreaBean
in your case) does not implement the Serializable
interface while it is been expected by the code behind. Fixing it is relatively simple, just let the class implement the Serializable
interface.
package bean;
import java.io.Serializable;
public class ProjectAreaBean implements Serializable {
private static final long serialVersionUID = 1L;
// ...
}
serialVersionUID
字段不是必需的,但强烈建议使用,因为这样可以保持类的不同版本与其实例的序列化表示之间的二进制兼容性。因此,当您稍后向类中添加新的可序列化字段时,您需要更改 serialVersionUID
字段(通常只需将其递增1就足够了)以防止出现问题对该类的旧版本的实例进行反序列化。像Eclipse这样的IDE还提供(重新)生成 serialVersionUID
值的选项,该值基本上是基于所有字段计算的哈希值。
The serialVersionUID
field is not necessary, but strongly recommended as this maintains the binary compatibility between different versions of the class and the serialized representations of its instances. So when you add later a new serializable field to the class, then you'd need to change the serialVersionUID
field (usually just incrementing it by 1 is sufficient) to prevent problems during deserialization of an instance of an older version of the class. IDEs like Eclipse also offer an option to (re)generate the serialVersionUID
value which is basically a hash computed based on all fields.
- 在Tomcat部署期间导致java.io.NotSerializableException的JSF托管bean
- 将非可序列化应用程序作用域bean注入可序列化会话作用域的托管属性群集中的bean
- 什么是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?
如果你的 Serializable
类反过来包含一个引用另一个类的实例的字段/属性,它绝对不能成为 Serializable
,那么你需要标记它 transient
。这样在类的序列化过程中就会跳过它。
If your Serializable
class contains in turn a field/property referencing an instance of another class which can absolutely not be made Serializable
, then you'd need to mark it transient
. This way it will be skipped during serialization of the class.
private transient SomeObject thisWillNotBeSerialized;
您需要了解,在反序列化后,此字段将始终变为 null
。请注意,在反序列化期间,类的构造函数和初始化块是不。如果您希望对序列化和反序列化进行更细粒度的控制,则覆盖 readObject()
和 writeObject()
方法。您可以在以下链接中找到具体示例:
You need to understand that after deserialization this field would always become null
. Note that the class' constructor and initialization blocks are not invoked during deserialization. If you'd like to have finer grained control over serialization and deserialization, then override the readObject()
and writeObject()
methods. You can find concrete examples in below links:
- Prevent component tree serialization for certain parts of application
- How to make persistent Cookies with a DefaultHttpClient in Android?
至于为什么你需要担心序列化,这是因为大多数Java servlet容器如Tomcat需要类来实现 Serializable
每当这些类的实例被存储为 HttpSession的属性
。这是因为当$ servlet容器需要关闭/重启或放在集群中时,可能需要将 HttpSession
保存在本地磁盘文件系统上,甚至通过网络传输其中会话必须同步的服务器。
As to the why you need to worry about serialization, this is because most Java servlet containers like Tomcat require classes to implement Serializable
whenever instances of those classes are been stored as an attribute of the HttpSession
. That is because the HttpSession
may need to be saved on the local disk file system or even transferred over network when the servlet container needs to shutdown/restart or is being placed in a cluster of servers wherein the session has to be synchronized.
为了能够在本地磁盘文件系统上保存Java对象或通过网络传输它们,必须首先将它们转换为字节流(基本上:a byte []
或 InputStream
)只有在对象后面的类实现序列化
。 Serializable
界面本身并没有真正做任何事情,它只是一个 标记界面 。
In order to be able to save Java objects on the local disk file system or transfer them over network, they have to be converted to a byte stream first (basically: a byte[]
or an InputStream
) and that is only possible if the class behind the object implements Serializable
. The Serializable
interface itself doesn't really do anything, it's merely a marker interface.
java.io.Serializable
javadoc- Java Object Serialization Specification
- Java Tutorials - Essential Classes - Basic I/O - Object Streams
这篇关于java.io.WriteAbortedException:写入已中止; java.io.NotSerializableException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!