java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException
catalina, jakarta-ee, java-io, notserializableexception, tomcat
Solution
Just implement `Serializable`
If you're getting a `NotSerializableException` like follows,
java.io.NotSerializableException: bean.ProjectAreaBean
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;
// ...
}
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.
See also:
- 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?
Mark unserializable fields `transient`
If your `Serializable` class contains in turn a field/property referencing an instance of another class which can absolutely not be made `Serializable` (usually, these represent resources, such as `InputStream`, `Connection`, etc), then you'd need to mark it `transient`. This way it will be skipped during serialization of the class.
private transient SomeObject thisWillNotBeSerialized;
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?
Why serialization?
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.
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. The code behind merely does an `instanceof Serializable` check on the session attribute to act accordingly.
See also:
- `java.io.Serializable` javadoc
- Java Object Serialization Specification
- Java Tutorials - Essential Classes - Basic I/O - Object Streams
Problem
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) ```
Related problems
- What is a serialVersionUID and why should I use it?
- 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
- How to make persistent Cookies with a DefaultHttpClient in Android?