java.io.WriteAbortedException:写入已中止; java.io.NotSerializableException [英] java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException

查看:1323
本文介绍了java.io.WriteAbortedException:写入已中止; 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.

  • 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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆