Pregunta

Actualmente estoy trabajando en un proyecto que debe persistir en cualquier tipo de objeto (de cuya implementación no tenemos ningún control) para que estos objetos puedan recuperarse posteriormente.

No podemos implementar un ORM porque no podemos restringir a los usuarios de nuestra biblioteca en el momento del desarrollo.

Nuestra primera alternativa fue serializarla con la serialización predeterminada de Java, pero tuvimos muchos problemas para recuperar los objetos cuando los usuarios empezaron a pasar diferentes versiones del mismo objeto (atributos cambiados tipos, nombres, ...).

Hemos intentado con la clase XMLEncoder (transforma un objeto en un XML), pero hemos encontrado que hay una falta de funcionalidad (por ejemplo, no es compatible con Enums).

Finalmente, también probamos JAXB pero esto impone a nuestros usuarios anotar sus clases.

¿Alguna buena alternativa?

¿Fue útil?

Solución

Lo más fácil que puede hacer es utilizar la serialización, IMO, pero pensar más en la forma serializada de las clases (lo que realmente debería hacer). Por ejemplo:

  1. Defina explícitamente el SerialUID.
  2. Defina su propio formulario serializado donde corresponda.

El formulario serializado es parte de la API de la clase y se debe pensar detenidamente en su diseño.

No voy a entrar en muchos detalles, ya que casi todo lo que he dicho viene de Effective Java. En su lugar, lo referiré a usted, específicamente a los capítulos sobre la serialización. Le advierte sobre todos los problemas con los que se encuentra y proporciona soluciones adecuadas para el problema:

http://www.amazon.com/Effective-Java-2nd-Joshua- Bloch / dp / 0321356683


Dicho esto, si aún está considerando un enfoque de no serialización, aquí hay un par:

Ajuste de XML

Como muchos han señalado es una opción, pero creo que todavía tendrá los mismos problemas con la compatibilidad con versiones anteriores. Sin embargo, con el ordenamiento de XML, es de esperar que los detecte de inmediato, ya que algunos marcos pueden hacer algunas comprobaciones durante la inicialización.

Conversión a / desde YAML

Esta es una idea con la que he estado jugando, pero me gustó mucho el formato YAML (al menos como un formato personalizado para String ()). Pero, en realidad, la única diferencia para usted es que usted se estaría convirtiendo a YAML en lugar de XML. El único beneficio es que YAML es un poco más legible para los humanos que XML. Se aplican las mismas restricciones.

Otros consejos

Es 2011, y en un proyecto de servicios web REST de calidad comercial, usamos los siguientes serializadores para ofrecer a los clientes una variedad de tipos de medios:

  • XStream (para XML pero no para JSON)
  • Jackson (para JSON)
  • Kryo (un formato de serialización binario rápido y compacto)
  • Smile (un formato binario que viene con Jackson 1.6 y versiones posteriores).
  • Serialización de objetos Java.

Hemos experimentado con otros serializadores recientemente:

  • SimpleXML parece sólido, funciona a 2 veces la velocidad de XStream, pero requiere demasiada configuración para nuestro situación.
  • YamlBeans tuvo un par de errores.
  • SnakeYAML tuvo un error menor relacionado con las fechas.

Jackson JSON, Kryo y Jackson Smile fueron todos significativamente más rápidos que la vieja y antigua Serialización de Objetos Java, de aproximadamente 3x a 4.5x. XStream está en el lado lento. Pero estas son todas opciones sólidas en este punto. Seguiremos vigilando a los otros tres.

http://x-stream.github.io/ es bueno, por favor tome un ¡Míralo! Muy conveniente

  

de cuya implementación no tenemos ningún control

La solución es no hagas esto . Si no tienes el control de la implementación de un tipo, no deberías serializarlo. Fin de la historia. La serialización de Java proporciona serialVersionUID específicamente para administrar las incompatibilidades de serialización entre diferentes versiones de un tipo. Si no controla la implementación, no puede estar seguro de que las ID se cambien correctamente cuando un desarrollador cambia una clase.

Tome un ejemplo simple de un 'Punto'. Puede representarse mediante un sistema de coordenadas cartesiano o polar. Sería un costo prohibitivo para usted construir un sistema que pudiera manejar dinámicamente este tipo de correcciones: realmente tiene que ser el desarrollador de la clase que diseña la serialización.

En resumen, su diseño es incorrecto, no la tecnología.

Google creó un protocolo binario: http://code.google.com/apis/ protocolbuffers / es más rápido, tiene una carga útil más pequeña en comparación con XML, lo que otros han sugerido como alternativa.

Una de las ventajas de los búferes de protocolo es que puede intercambiar información con C, C ++, python y java.

Intente serializar a json con Gson por ejemplo.

También es un reemplazo directo de serialización JDK muy rápido: http://ruedigermoeller.github.io/fast-serialization/

Si la velocidad de serialización es importante para usted, hay un punto de referencia completo de los serializadores JVM aquí:

Personalmente, uso mucho Fame , ya que presenta interoperabilidad con Smalltalk (tanto VW como Squeak) y Python. (Descargo de responsabilidad, soy el principal contribuyente del proyecto Fame).

Posiblemente Castor ?

Betwixt es una buena biblioteca para serializar objetos, pero no va a ser un tipo automático de cosa Si la cantidad de objetos que tiene que serializar es relativamente fija, esta puede ser una buena opción para usted, pero si su 'cliente' le lanzará nuevas clases todo el tiempo, puede que cueste más esfuerzo de lo que vale ( Definitivamente más fácil que XMLEncoder para todos los casos especiales, sin embargo).

Otro enfoque es exigir a su cliente que proporcione los archivos .betwixt adecuados para cualquier objeto que le arrojen (lo que efectivamente les exime de la responsabilidad).

Larga y corta: la serialización es difícil : no existe un enfoque completamente cerebral. La serialización de Java es lo más cercano a una solución de muerte mental que he visto, pero como ha encontrado, el uso incorrecto del valor de la versión uid puede romperla. La serialización de Java también requiere el uso de la interfaz del marcador 'Serializable', por lo que si no puedes controlar tu fuente, no tienes suerte con eso.

Si el requisito es realmente tan arduo como lo describe, es posible que tenga que recurrir a algún tipo de BCE (modificación del código Byte) en los objetos / aspectos / lo que sea. Esto se está saliendo del ámbito de un pequeño proyecto de desarrollo, y en el ámbito de Hibernate, Casper o un ORM ...

Otra idea: usar caché. Los cachés proporcionan un mejor control, escalabilidad y robustez a la aplicación. Sin embargo, aún es necesario serializar, pero la administración se vuelve mucho más fácil dentro de un marco de servicio de almacenamiento en caché. La memoria caché se puede conservar en la memoria, el disco, la base de datos o la matriz, o todas las opciones, con una de ellas desbordada, en espera y conmutación por error para la otra. Commons JCS y Ehcache son dos implementaciones de Java, esta última es una solución empresarial gratuita de hasta 32 GB de almacenamiento (descargo de responsabilidad: no trabajo para ehcache ;-)).

SBE es una biblioteca establecida para una biblioteca de serialización rápida, basada en bytebuffer y capaz de versiones. Sin embargo, es un poco difícil de usar, ya que necesita escribir clases de envoltura de longitud sobre él.

A la luz de sus deficiencias, recientemente he creado una biblioteca de serialización solo para Java inspirada en el protocolo FIX y SBE (protocolo común del mercado financiero para intercambiar mensajes de comercio / cotización), que intenta mantener las ventajas de ambos al superar sus debilidades Puede consultar https://github.com/iceberglet/anymsg

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top