Serialización de Java: ventajas y desventajas, ¿usar o evitar? [cerrado]

20

La serialización se utiliza para la persistencia en Java. Puede estar bien persistir algunos objetos usando la serialización. Pero, para una gran cantidad de objetos, ORM, base de datos, etc. podrían ser mejores. Parece que la serialización es útil solo para trabajos pequeños. Tal vez yo estoy equivocado. Entonces, ¿cuáles son las ventajas de la serialización sobre los métodos de no serialización? ¿Cuándo debe usarse y cuándo debe evitarse?

Esta pregunta me vino a la mente después de ver el artículo de DZone ¿Es mala la serialización de objetos?

Y estas son las líneas que dieron lugar a mi pregunta:

Si observa Java y sus objetos de sesión, se utiliza la serialización de objetos puros. Suponiendo que una sesión de aplicación es de corta duración, es decir, como máximo unas pocas horas, la serialización de objetos es simple, bien soportada y está integrada en el concepto Java de una sesión. Sin embargo, cuando la persistencia de los datos es durante un período de tiempo más largo, posiblemente días o semanas, y tiene que preocuparse por las nuevas versiones de la aplicación, la serialización se vuelve malvada rápidamente. Como cualquier buen desarrollador de Java sabe, si planea serializar un objeto, incluso en una sesión, necesita un ID de serialización real (serialVersionUID), no solo un 1L, y necesita implementar la interfaz serializable. Sin embargo, la mayoría de los desarrolladores no conocen las reglas reales detrás del proceso de deserialización de Java. Si su objeto ha cambiado, más que simplemente agregar campos simples al objeto, es posible que Java no pueda deserializar el objeto correctamente incluso si la ID de serialización no ha cambiado. De repente, ya no puede recuperar sus datos, lo cual es inherentemente malo.

Ahora, los desarrolladores que lean esto pueden decir que nunca escribirían código que tuviera este problema. Eso puede ser cierto, pero ¿qué pasa con una biblioteca que usa o algún otro desarrollador que ya no es empleado de su empresa? ¿Puede garantizar que este problema nunca sucederá? La única forma de garantizarlo es utilizar un método de serialización diferente.

rascacielos
fuente
¿Le importaría ampliar un poco lo que específicamente en el artículo mencionado causó su pregunta?
mosquito
@gnat: agregó las líneas a la pregunta.
rascacielos el
La parte sobre 'no solo un 1L' no es correcta.
user207421

Respuestas:

15

La serialización se usa principalmente en dos áreas:

  • creación de prototipos de persistencia

    prácticamente todos los gráficos de objetos se pueden convertir en serializables rápidamente, para pruebas rápidas de conceptos o aplicaciones rápidas y sucias, esto podría ser más rápido que configurar una capa ORM real u otro sistema de persistencia

  • almacenamiento a corto plazo de objetos casi arbitrarios:

    Los servidores de aplicaciones, por ejemplo, tienden a persistir la información de la sesión utilizando la serialización. Esto tiene la ventaja de que los valores en la sesión pueden ser de casi cualquier tipo (siempre que sea serializable).

Para casi todos los demás usos, los inconvenientes que usted (y el artículo) menciona son demasiado grandes: el formato exacto es difícil de mantener estable, los cambios de clase pueden hacer que sus datos serializados sean ilegibles fácilmente, leer / escribir los datos en código que no sea Java es casi imposible (o al menos mucho más difícil de lo necesario).

JAXB y tecnologías similares proporcionan funciones similares con un costo igualmente bajo, al tiempo que reducen algunos de los problemas.

Joachim Sauer
fuente
No llamaría a JAXB 'bajo costo': el esquema debe escribirse.
Kevin Cline
3
@kevincline: no necesita un esquema con JAXB, es completamente opcional (e incluso puede generarlo desde sus clases, si lo desea). Además: si JAXB no es útil por alguna razón, hay muchas alternativas, como los XML Beans que funcionan igual de bien.
Joachim Sauer
12

Utilizo la serialización de objetos para permitir el análisis post mortem en caso de un error inesperado en la producción. Las entradas para un cálculo se serializan en un archivo de datos. Si se informa un error, un programa simple puede volver a cargar las entradas y volver a ejecutar el cálculo con un depurador adjunto. O bien, se puede utilizar un shell maravilloso para recargar los objetos y modificarlos si lo desea.

También utilizamos la serialización para pasar objetos Java a través de HTTP a un servicio web. Mucho más fácil que serializar hacia y desde el texto. La desventaja es que las instalaciones del cliente y el servidor deben implementarse juntas, pero eso no es un problema ya que controlamos ambos extremos.

Kevin Cline
fuente
3
¡Ese es un caso de uso interesante! ¡Demasiado pequeño para requerir un sistema "más complejo" y la mayoría de los inconvenientes no se aplican!
Joachim Sauer
Ahora hemos escrito un analizador post-mortem que usa POI para construir una hoja de cálculo a partir de los objetos Java para una visualización más fácil. Esto nos ha ahorrado muchas horas de examen del archivo de registro.
Kevin Cline
7

¿Cuáles son las ventajas de la serialización sobre los métodos de no serialización?

La serialización de Java tiene algunas ventajas:

  • Integrado en el sistema : no necesita confiar en herramientas, bibliotecas o configuraciones de terceros.

  • Relativamente simple de entender , al menos al principio.

  • Todo desarrollador lo sabe (o debería). Independientemente de si los desarrolladores de Java aprueban o desaprueban, es probable que estén familiarizados con la serialización de objetos Java.

Y, por supuesto, hay desventajas:

  • Evita el flujo estándar de Java. Asigna memoria pero no llama a un constructor, por lo que los campos transitorios no se inicializan. Los campos se inicializan en orden alfabético, no en orden de origen.

  • No es tan eficiente en términos de espacio, pero tampoco es horrible. Es posible que desee comprimir el resultado.

  • Frágil a menos que tome precauciones cuando cambien sus objetos. Y aún entonces.

¿Cuándo debe usarse y cuándo debe evitarse?

Usar cuando :

  • El tamaño del despliegue es importante. Integrado en el sistema, por lo que 0 bytes adicionales.

  • Todos los actores usarán versiones compatibles.

  • El almacenamiento a largo plazo no es un problema.

Evitar cuando :

  • Cualquiera de los anteriores no se aplica.
JvR
fuente
3

La serialización y un ORM / base de datos son cosas diferentes, aunque hay cierta superposición.

Un objeto serializado representa toda la información necesaria para "descongelar" un objeto persistente y repoblar sus datos. Un ORM y una base de datos conservan los datos en una base de datos. Una clase puede tener campos de información que el ORM no almacena en la base de datos, por ejemplo, el campo calculado.

Además, la serialización y un ORM están resolviendo diferentes problemas. La serialización resuelve el problema de persistir un gráfico de objeto en una secuencia (memoria, sistema de archivos, etc.). Un ORM maneja el mapeo de piezas de información a las columnas de la base de datos y la recuperación e instanciación de objetos, además de proporcionar detalles como la búsqueda y la carga diferida.

Use un ORM cuando desee conservar datos en una base de datos para situaciones en las que está tratando con grandes cantidades de datos o necesita informes, búsquedas / consultas, almacenamiento u otras cosas en las que las bases de datos son buenas. Use la serialización cuando desee guardar una representación de su (s) estructura (s) de datos en el disco.

Sam
fuente
0

La serialización rara vez se usa en la práctica.

Como ya se mencionó, el caso de uso más común para la serialización es almacenar objetos como blobs en una base de datos de sesión. Esto funciona bien por dos razones: las sesiones tienden a ser de corta duración y la base de datos de la sesión no sabe cómo mapear objetos arbitrarios a un modelo relacional.

Para los datos que deben conservarse durante largos períodos de tiempo (como un carrito de compras de Amazon), la mejor práctica es almacenar esos datos en una base de datos.

El mecanismo de persistencia de la sesión garantiza que un usuario con una sesión activa se devuelva al mismo servidor. Solo se accede a la base de datos de la sesión cuando falla un servidor y el usuario es redirigido a un nuevo servidor. El nuevo servidor detecta una sesión activa, pero no la encuentra en la memoria, por lo que intenta recuperarla de la base de datos de la sesión en un intento de proporcionar una experiencia perfecta al usuario.

Hay dos problemas con este enfoque:

Primero, el vaciado de datos de sesión a la base de datos de sesión es un proceso lento. El vaciado de datos de sesión con demasiada frecuencia degrada el rendimiento, y la mayoría de los servidores están configurados para vaciar cada 30 segundos, o cada minuto, o más. Esta solución de conmutación por error "parecida" nunca es 100% efectiva.

En segundo lugar, mi experiencia es que la mayoría de los clientes están de acuerdo en que arrojar un mensaje de error pidiéndole al usuario que inicie sesión e intente nuevamente durante las raras instancias en que falla un servidor. En este caso, apagamos la base de datos de sesión por completo y disfrutamos del aumento de rendimiento.

Otro uso de la serialización es proporcionar tiempos de respuesta más rápidos mediante el uso de marcos como Flex que utilizan la serialización y la compresión de gráficos de objetos para las interacciones servidor-cliente.

Como otros han señalado, hay algunas razones creativas y útiles para emplear la serialización, pero estas son raras en la práctica.

Históricamente, la serialización es difícil de implementar correctamente y la confiabilidad, restringiendo su uso a un pequeño número de casos. La mayoría de los desarrolladores nunca serializarán objetos ellos mismos, pero pueden confiar en los marcos que lo hacen detrás de escena.

eric w
fuente
2
"La serialización rara vez se usa en la práctica". - La serialización a menudo se llama en el mundo de los servicios web REST. La mayoría de las veces, solo se trata de cadenas y números enteros o similares, pero es algo real y los objetos más complejos necesitan ser conscientes de ello. Decir que rara vez se usa ignora una gran franja de dominios que lo usan con frecuencia.
0

Respuesta corta a "cuándo usar la serialización de Java" y "cuándo evitar la serialización de Java"

Use la serialización Java si

  • poca codificación debería ser necesaria
  • no importa que los datos binarios no sean legibles por humanos
  • no es necesario buscar en datos serializados (no es posible realizar una consulta similar a la base de datos)
  • ya sea
    • la estructura de datos serializados no cambia o
    • no importa si los datos serializados almacenados ya no son legibles después del "cambio de estructura de datos" (es decir, datos de sesión en una aplicación web)

En todas las demás situaciones, la "serialización binaria de Java" es mala

Alternativas

  • serialización xml
  • base de datos nosql
  • base de datos relacional con ORM
k3b
fuente