example - set icon java
¿Cuál es la mejor alternativa para la serialización de Java? (12)
Actualmente estoy trabajando en un proyecto que necesita persistir en cualquier tipo de objeto (de la cual 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 comenzaron a pasar diferentes versiones del mismo objeto (atributos, tipos cambiados, nombres, ...).
Hemos intentado con la clase XMLEncoder (transforma un objeto en un XML), pero descubrimos que hay una falta de funcionalidad (por ejemplo, no admite Enums).
Finalmente, también probamos JAXB pero esto impone a nuestros usuarios anotar sus clases.
¿Alguna buena alternativa?
de la cual no tenemos ningún control
La solución es no hacer esto . Si no tiene control de la implementación de un tipo, no debería serializarlo. Fin de la historia. La serialización de Java proporciona serialVersionUID específicamente para administrar incompatibilidades de serialización entre diferentes versiones de un tipo. Si no controla la implementación, no puede estar seguro de que los ID se modifiquen correctamente cuando un desarrollador cambia de clase.
Tome un ejemplo simple de un ''Punto''. Puede ser representado por un sistema de coordenadas cartesianas o polares. Sería un costo prohibitivo para usted construir un sistema que pudiera hacer frente dinámicamente a este tipo de correcciones; realmente tiene que ser el desarrollador de la clase que diseña la serialización.
En resumen, es su diseño lo que está mal, no la tecnología.
Es 2011, y en un proyecto de servicios web REST de calidad comercial, utilizamos 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.
Experimentamos con otros serializadores recientemente:
- SimpleXML parece sólido, funciona a 2 veces la velocidad de XStream, pero requiere demasiada configuración para nuestra situación.
- YamlBeans tuvo un par de errores.
- SnakeYAML tenía un pequeño error relacionado con las fechas.
Jackson JSON, Kryo y Jackson Smile fueron significativamente más rápidos que la antigua Serialización de objetos Java, por aproximadamente 3x a 4.5x. XStream está en el lado lento. Pero estas son todas elecciones sólidas en este punto. Seguiremos monitoreando los otros tres.
Google creó un protocolo binario: http://code.google.com/apis/protocolbuffers/ es más rápido, tiene una carga más pequeña en comparación con XML, 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.
Lo más fácil para usted es seguir usando la serialización, IMO, pero piense más en la forma serializada de las clases (que de todos modos debería hacer). Por ejemplo:
- Defina explícitamente el SerialUID.
- Defina su propio formulario serializado cuando sea apropiado.
La forma serializada es parte de la API de la clase y se debe pensar cuidadosamente en su diseño.
No entraré en muchos detalles, ya que prácticamente todo lo que dije proviene de Java efectivo. En cambio, lo referiré a él, específicamente los capítulos sobre Serialización. Le advierte sobre todos los problemas con los que se está tropezando y le brinda soluciones adecuadas al problema:
http://www.amazon.com/Effective-Java-2nd-Joshua-Bloch/dp/0321356683
Dicho esto, si todavía está considerando un enfoque de no serialización, aquí hay un par:
Clasificación de XML
Como muchos han señalado es una opción, pero creo que todavía se encontrará con los mismos problemas con la compatibilidad con versiones anteriores. Sin embargo, con XML marshalling, con suerte los detectará de inmediato, ya que algunos frameworks pueden hacer algunas comprobaciones durante la inicialización.
Conversión a / desde YAML
Esta es una idea con la que he estado jugando, pero realmente me gustó el formato YAML (al menos como un formato personalizado toString ()). Pero, en realidad, la única diferencia para usted es que se dirigiría a YAML en lugar de XML. El único beneficio es que ese YAML es un poco más legible para humanos que XML. Se aplican las mismas restricciones.
Otra idea: usar caché. Las 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 servicios de caché. La memoria caché puede persistir en la memoria, el disco, la base de datos o la matriz, o todas las opciones, y una de ellas es desbordamiento, espera, conmutación por error para la otra. Commons JCS y Ehcache son dos implementaciones de Java, la última es una solución empresarial libre de hasta 32 GB de almacenamiento (descargo de responsabilidad: no trabajo para ehcache ;-)).
Personalmente, uso Fame mucho, ya que presenta interoperabilidad con Smalltalk (tanto VW y Squeak) como con Python. (Descargo de responsabilidad, soy el principal colaborador del proyecto de Fama).
Posiblemente Castor ?
Si la velocidad de serialización es importante para usted, entonces hay una referencia completa de los serializadores JVM aquí:
También un reemplazo de reemplazo de serialización JDK muy rápido: http://ruedigermoeller.github.io/fast-serialization/
Betwixt es una buena biblioteca para serializar objetos, pero no va a ser un tipo automático de cosas. Si el número de objetos que tiene que serializar es relativamente fijo, esta puede ser una buena opción para usted, pero si su "cliente" va a tirarle nuevas clases todo el tiempo, puede ser más esfuerzo de lo que vale ( Definitivamente más fácil que XMLEncoder para todos los casos especiales, sin embargo).
Otro enfoque es exigirle a su cliente que proporcione los archivos .betwixt adecuados para cualquier objeto que le arrojen (que efectivamente les libera de la responsabilidad).
Largo y corto: la serialización es difícil , no hay un enfoque completamente cerebralmente muerto. La serialización de Java es lo más parecido a una solución de muerte cerebral que he visto en mi vida, pero como ha visto, el uso incorrecto del valor del uid de la versión puede romperlo. La serialización de Java también requiere el uso de la interfaz del marcador "Serializable", por lo que si no puede controlar su fuente, no tendrá suerte con esa.
Si el requisito es realmente tan arduo como usted lo describe, puede que tenga que recurrir a algún tipo de BCE (modificación del código Byte) en los objetos / aspectos / lo que sea. Esto está saliendo del ámbito de un pequeño proyecto de desarrollo, y en el reino de Hibernate, Casper o un ORM ....
XStream es bueno, ¡échale un vistazo! Muy conveniente