The other answers here explain serialization well. Since this is the first result in Google I wanted to add information that really helped me resolve the issue.
The exception message itself does not indicate which field in which class caused this issue. If you can't make a class serializable and need to add the transient keyword so Java does not try to serialize a field it can be tricky to figure out which field is causing the issue.
If you add the parameter -Dsun.io.serialization.extendedDebugInfo=true
to Java/Tomcat when starting it the exception will be much more useful. Here is an example of what the exception message will look like:
java.io.NotSerializableException: za.co.abc.presentation.control.Three
- field (class "za.co.abc.presentation.control.Two", name: "three", type: "class za.co.abc.presentation.control.Three")
- object (class "za.co.abc.presentation.control.Two", za.co.abc.presentation.control.Two@fbbb20)
- field (class "za.co.abc.presentation.control.One", name: "two", type: "class za.co.abc.presentation.control.Two")
- object (class "za.co.abc.presentation.control.One", za.co.abc.presentation.control.One@17ee6c9)
- field (class "za.co.abc.presentation.control.Trail", name: "one", type: "class za.co.abc.presentation.control.One")
- root object (class "za.co.abc.presentation.control.Trail", {/click-tests/home.htm=home})
If you do use the transient keyword to make fields not serialize you probably have to then set those fields when the class is read. You have to implement the readObject() method to do that. Here is an example:
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
// magically read all non-transient fields from input stream and populate their values
in.defaultReadObject();
someTransientField = new NotSerializableClass();
}