java ee - java.io.WriteAbortedException: escritura abortada; java.io.NotSerializableException
java-ee tomcat (2)
¿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)
Necesita hacer que bean.ProjectAreaBean
serializable.
Solo implemente Serializable
Si obtiene una NotSerializableException
siguiente manera,
java.io.NotSerializableException: bean.ProjectAreaBean
entonces simplemente significa que la clase identificada por el nombre completamente calificado en el mensaje de excepción (que es bean.ProjectAreaBean
en su caso) no implementa la interfaz Serializable
mientras que el código detrás la espera. Repararlo es relativamente simple, solo deja que la clase implemente la interfaz Serializable
.
package bean;
import java.io.Serializable;
public class ProjectAreaBean implements Serializable {
private static final long serialVersionUID = 1L;
// ...
}
El campo serialVersionUID
no es necesario, pero es muy recomendable ya que mantiene la compatibilidad binaria entre las diferentes versiones de la clase y las representaciones serializadas de sus instancias. Entonces, cuando agregue más tarde un nuevo campo serializable a la clase, entonces necesitaría cambiar el campo serialVersionUID
(generalmente solo incrementarlo en 1 es suficiente) 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 valor serialVersionUID
, que básicamente es un cálculo hash basado en todos los campos.
Ver también:
- JSF gestionó bean causando java.io.NotSerializableException durante la implementación de Tomcat
- Inyectar bean con ámbito de aplicación no serializable como propiedad administrada de bean con ámbito de sesión serializable en un clúster
- ¿Qué es un serialVersionUID y por qué debería usarlo?
Marcar campos transient
serializables
Si su clase Serializable
contiene a su vez un campo / propiedad que hace referencia a una instancia de otra clase que no puede convertirse en Serializable
, entonces deberá marcarla transient
. De esta forma, se omitirá durante la serialización de la clase.
private transient SomeObject thisWillNotBeSerialized;
Debes entender que después de la deserialización este campo siempre se volverá null
. Tenga en cuenta que el constructor de clase y los bloques de inicialización no se invocan durante la deserialización. Si desea tener un control detallado sobre la serialización y la deserialización, anule los readObject()
y writeObject()
. Puede encontrar ejemplos concretos en los enlaces a continuación:
- Evitar la serialización del árbol de componentes para ciertas partes de la aplicación
- ¿Cómo hacer cookies persistentes con un HTTP predeterminado en Android?
¿Por qué serialización?
En cuanto a por qué necesita preocuparse por la serialización, esto se debe a que la mayoría de los contenedores de servlets de Java como Tomcat requieren clases para implementar Serializable
siempre que las instancias de esas clases se almacenen como un atributo de la HttpSession
. Esto se debe a que la HttpSession
puede necesitar guardarse en el sistema de archivos del disco local o incluso transferirse a través de la red cuando el contenedor del servlet debe apagarse / reiniciarse o se está colocando en un clúster 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 tienen que convertirse en un flujo de bytes (básicamente: un byte[]
o un InputStream
) y eso solo es posible si la clase detrás del objeto implementa Serializable
. La interfaz Serializable
en sí misma no hace nada, es simplemente una interfaz de marcador .