java.io.WriteAbortedException: escritura cancelada; java.io.NotSerializableException
¿Qué causa este tipo de error en 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)
Solo implementaSerializable
Si recibes un NotSerializableException
Me gusta, sigue,
java.io.NotSerializableException: bean.ProjectAreaBean
entonces simplemente significa que la clase identificada por el nombre completo en el mensaje de excepción (que es bean.ProjectAreaBean
en su caso) no implementa la Serializable
interfaz mientras el código subyacente lo espera. Arreglarlo es relativamente simple, simplemente deje que la clase implemente la Serializable
interfaz.
package bean;
import java.io.Serializable;
public class ProjectAreaBean implements Serializable {
private static final long serialVersionUID = 1L;
// ...
}
El serialVersionUID
campo no es necesario, pero se recomienda encarecidamente ya que mantiene la compatibilidad binaria entre diferentes versiones de la clase y las representaciones serializadas de sus instancias. Entonces, cuando agregue más adelante un nuevo campo serializable a la clase, deberá cambiar el serialVersionUID
campo (generalmente basta con incrementarlo en 1) para evitar problemas durante la deserialización de una instancia de una versión anterior de la clase. Los IDE como Eclipse también ofrecen una opción para (re)generar el serialVersionUID
valor, que es básicamente un hash calculado en función de todos los campos.
Ver también:
- Bean administrado JSF que causa java.io.NotSerializableException durante la implementación de Tomcat
- Inyectar un bean con ámbito de aplicación no serializable como propiedad administrada de un bean con ámbito de sesión serializable en un clúster
- ¿Qué es un serialVersionUID y por qué debería usarlo?
Marcar campos no serializablestransient
Si su Serializable
clase contiene a su vez un campo/propiedad que hace referencia a una instancia de otra clase que no se puede crear en absoluto Serializable
(por lo general, estos representan recursos, como InputStream
, Connection
etc.), entonces deberá marcarlo transient
. De esta manera se omitirá durante la serialización de la clase.
private transient SomeObject thisWillNotBeSerialized;
Debe comprender que después de la deserialización este campo siempre se convertirá en null
. Tenga en cuenta que el constructor de la clase y los bloques de inicialización no se invocan durante la deserialización. Si desea tener un control más detallado sobre la serialización y deserialización, anule los métodos readObject()
y writeObject()
. Puede encontrar ejemplos concretos en los siguientes enlaces:
- Evitar la serialización del árbol de componentes para ciertas partes de la aplicación
- ¿Cómo hacer Cookies persistentes con un DefaultHttpClient en Android?
¿Por qué serialización?
En cuanto a por qué debe preocuparse por la serialización, esto se debe a que la mayoría de los contenedores de servlets Java como Tomcat requieren clases para implementarse Serializable
siempre que las instancias de esas clases se almacenen como un atributo del archivo HttpSession
. Esto se debe a que es HttpSession
posible que sea necesario guardarlo en el sistema de archivos del disco local o incluso transferirlo a través de la red cuando el contenedor de servlets necesita apagarse/reiniciarse o se coloca en un grupo de servidores donde la sesión debe sincronizarse.
Para poder guardar objetos Java en el sistema de archivos del disco local o transferirlos a través de la red, primero deben convertirse en un flujo de bytes (básicamente: a byte[]
o an InputStream
) y eso solo es posible si la clase detrás del objeto implementa Serializable
. La Serializable
interfaz en sí misma realmente no hace nada, es simplemente una interfaz de marcador . El código subyacente simplemente verifica instanceof Serializable
el atributo de sesión para actuar en consecuencia.
Ver también:
java.io.Serializable
javadoc- Especificación de serialización de objetos Java
- Tutoriales de Java - Clases esenciales - E/S básicas - Flujos de objetos
Necesitas hacerlo bean.ProjectAreaBean
serializable.