Je travaille actuellement sur un projet qui doit conserver n'importe quel type d'objet (dont nous n'avons aucun contrôle sur la mise en œuvre) pour que ces objets puissent être récupérés ultérieurement.
Nous ne pouvons pas mettre en œuvre un ORM car nous ne pouvons pas restreindre les utilisateurs de notre bibliothèque au moment du développement.
Notre première alternative consistait à le sérialiser avec la sérialisation par défaut Java, mais nous avions beaucoup de difficulté à récupérer les objets lorsque les utilisateurs commençaient à transmettre différentes versions du même objet (types, attributs, noms modifiés, etc.).
Nous avons essayé avec la classe XMLEncoder (transforme un objet en XML), mais nous avons constaté un manque de fonctionnalités (ne prend pas en charge Enums, par exemple).
Enfin, nous avons également essayé JAXB mais cela impose à nos utilisateurs d’annoter leurs classes.
Une bonne alternative?
La chose la plus facile à faire pour vous est toujours d’utiliser la sérialisation, IMO, mais de réfléchir davantage à la forme sérialisée des classes (ce que vous devriez vraiment faire de toute façon). Par exemple:
La forme sérialisée fait partie de l'API de la classe et sa conception doit être pensée avec soin.
Je n’entrerai pas dans les détails, car à peu près tout ce que j’ai dit vient de Effective Java. Je vais plutôt vous y référer, plus précisément aux chapitres sur la sérialisation. Il vous avertit de tous les problèmes que vous rencontrez et vous apporte les solutions appropriées:
http://www.Amazon.com/Effective-Java-2nd-Joshua-Bloch/dp/0321356683
Cela dit, si vous envisagez toujours une approche de non-sérialisation, voici quelques solutions:
Marshalling XML
Comme beaucoup l'ont fait remarquer, c'est une option, mais je pense que vous rencontrez toujours les mêmes problèmes de compatibilité ascendante. Cependant, avec le marshalling XML, nous espérons pouvoir les récupérer tout de suite, car certains frameworks peuvent effectuer certaines vérifications lors de l'initialisation.
Conversion vers/depuis YAML
C’est une idée à laquelle je me suis attaché, mais j’ai vraiment aimé le format YAML (au moins comme format personnalisé toString ()). Mais, en réalité, la seule différence est que vous vous dirigeriez vers YAML au lieu de XML. Le seul avantage est que YAML est légèrement plus lisible que XML. Les mêmes restrictions s'appliquent.
Nous sommes en 2011 et dans un projet de services Web REST de qualité commerciale, nous utilisons les sérialiseurs suivants pour offrir aux clients une variété de types de supports:
Nous avons récemment expérimenté d'autres sérialiseurs:
Jackson JSON, Kryo et Jackson Smile étaient tous nettement plus rapides que la bonne vieille sérialisation des objets Java, d’environ 3x à 4,5x. XStream est un peu lent. Mais ce sont tous des choix solides à ce stade. Nous continuerons à surveiller les trois autres.
http://x-stream.github.io/ est Nice, jetez-y un coup d'oeil! Très pratique
dont nous n'avons aucun contrôle sur la mise en œuvre
La solution est ne fais pas cela . Si vous n'avez pas le contrôle de l'implémentation d'un type, vous ne devriez pas le sérialiser. Fin de l'histoire. La sérialisation Java fournit serialVersionUID spécifiquement pour gérer les incompatibilités de sérialisation entre les différentes versions d'un type. Si vous ne contrôlez pas l'implémentation, vous ne pouvez pas être sûr que les ID sont modifiés correctement lorsqu'un développeur modifie une classe.
Prenons un exemple simple de "Point". Il peut être représenté par un système de coordonnées cartésien ou polaire. Construire un système capable de gérer de manière dynamique ce type de corrections aurait un coût prohibitif. Il doit s'agir en réalité du développeur de la classe qui conçoit la sérialisation.
En bref, c'est votre conception qui ne va pas - pas la technologie.
google a mis au point un protocole binaire - http://code.google.com/apis/protocolbuffers/ est plus rapide, sa charge utile est inférieure à celle de XML, ce que d’autres ont suggéré comme solution de rechange.
L’un des avantages des tampons de protocole est qu’il peut échanger des informations avec C, C++, Python et Java.
Également un remplacement très rapide de la série JDK: http://ruedigermoeller.github.io/fast-serialization/
Essayez de sérialiser JSON avec Gson par exemple.
Si la rapidité de la sérialisation est importante pour vous, vous trouverez ici un exemple complet des sérialiseurs JVM:
Personnellement, j'utilise Fame beaucoup, car il offre une interopérabilité avec Smalltalk (VW et Squeak) et Python. (Avertissement, je suis le principal contributeur du projet Fame.)
Betwixt est une bonne bibliothèque pour la sérialisation d'objets - mais cela ne sera pas automatique. Si le nombre d'objets que vous devez sérialiser est relativement fixe, cela peut être une bonne option pour vous, mais si votre 'client' doit vous lancer de nouvelles classes tout le temps, cela peut demander plus d'effort qu'il ne vous en coûte ( Certainement plus facile que XMLEncoder pour tous les cas particuliers, cependant).
Une autre approche consiste à demander à votre client de fournir les fichiers .betwixt appropriés pour tous les objets qu’il vous envoie (ce qui leur permet de se décharger de toute responsabilité).
Long et court - la sérialisation est hard - il n'y a pas d'approche complètement morte de cerveau. La sérialisation Java est aussi proche d'une solution cérébrale que je ne l'ai jamais vue, mais comme vous l'avez constaté, une utilisation incorrecte de la valeur de version uid peut la perturber. La sérialisation Java nécessite également l'utilisation de l'interface de marqueur 'Serializable', donc si vous ne pouvez pas contrôler votre source, vous aurez un peu de malchance avec celle-là.
Si l'exigence est vraiment aussi ardue que vous le décrivez, vous devrez peut-être recourir à une sorte de BCE (modification du code byte) sur les objets/aspects/peu importe. Cela sort du domaine des petits projets de développement et du domaine de Hibernate, Casper ou d'un ORM ...
Peut-être Castor ?
Une autre idée: utiliser le cache. Les caches offrent un contrôle, une évolutivité et une robustesse bien meilleurs pour l'application. Encore faut-il sérialiser, cependant, mais la gestion devient beaucoup plus facile avec un framework de service de mise en cache. Le cache peut être conservé dans la mémoire, le disque, la base de données ou le tableau (ou toutes les options), l'une étant un dépassement de capacité, une mise en veille, un basculement pour l'autre. Commons JCS et Ehcache sont deux implémentations Java, cette dernière est une solution d'entreprise offrant jusqu'à 32 Go de stockage (avertissement: je ne travaille pas pour ehcache ;-)).