IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Java Discussion :

[Projet] Mon projet de sérialisation Java "universelle"


Sujet :

Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 326
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 326
    Billets dans le blog
    12
    Par défaut [Projet] Mon projet de sérialisation Java "universelle"
    Bonjour,

    Aujourd'hui je souhaiterais vous présenter mon projet universal-serializer (lien GitHub) pour sérialiser/désérialiser des objets Java à l'aide d'une interface commune Serializer.

    L'objectif ? Simplifier le développement. En effet, lorsque vous utilisez des méthodes pour transformer vos objets d'un format vers un autre vous :
    • Utilisez souvent plus d'une instruction
    • Effectuez des recherches dans la JavaDoc pour trouver la méthode qui convient
    • Pouvez oublier de fermer vos flux


    Cet API gère actuellement plusieurs formats :
    • Binaire, avec 2 implémentations : Sérialisation Java, Google Protocol Buffers
    • Fichier, avec 2 implémentations : CSV, Excel (XLS et XLSX)
    • Texte, avec 4 implémentations : JWT (JSON Web Tokens), XML (JAXB), Base64, Base64 URL


    Présentation de l'interface Serializer :
    • serialize(X myObject) : Y Sérialise un objet Java vers un autre format (binaire, texte, ou fichier).
    • deserialize(Y myData) : X Désérialise un format de donnée vers un objet Java (opération inverse de serialize())
    • sendTo(X myObject, OutputStream out) : void Sérialise un objet Java et l'envoi dans un flux (utile pour du développement réseaux)
    • receiveFrom(InputStream in) : X Récupère un objet Java à partir d'un flux (utile pour du développement réseaux)


    Voici un exemple d'utilisation pour chaque format :
    Code Java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    // Sérialisation Java
    JavaSerializer<MyClass> s = new JavaSerializer<>();
    byte[] byteArray = s.serialize(new MyClass(/* init */));
    MyClass deserialized = s.deserialize(byteArray);
    Code Java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    // Sérialisation Excel
    ExcelSerializer<MyClass> s = new ExcelSerializer<>(MyClass.class /* , your FileOptions */);
    Path path = s.serialize(new ArrayList<MyClass>());
    List<MyClass> deserialized = s.deserialize(path);
    Code Java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    // Sérialisation JWT
    String SECRET = "546T78UINqqsvfzfs<vs<sdv_-('U87Y89YG87";
    JwtSerializer<MyClass> s = new JwtSerializer<>(MyClass.class, Algorithm.HS256, SECRET);
    String jsonWebToken = s.serialize(new MyClass(/* init */));
    MyClass deserialized = s.deserialize(jsonWebToken);

    Questions :
    1. Que pensez-vous de ce projet ? Vous semble-t-il suffisamment intéressant pour être utilisé dans vos projets ?
    2. Quels sont les implémentations que vous souhaiteriez voir apparaitre dans l'API ? (Mis à part JSON, que je ne compte pas implémenter)
    3. Si vous aviez à changer les dépendances du pom.xml, mettriez-vous des dépendances en optional true ?

    Note : En ce qui concerne le nom du projet, j'ai pensé à une télécommande universelle


    Merci pour vos retours
    N'hésitez pas à consulter la FAQ Java, lire les cours et tutoriels Java, et à poser vos questions sur les forums d'entraide Java

    Ma page Developpez | Mon profil Linkedin | Vous souhaitez me contacter ? Contacter Gokan EKINCI

  2. #2
    Membre Expert
    Inscrit en
    Mai 2006
    Messages
    1 364
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 1 364
    Par défaut
    Je n'ai jamais eu le besoin de serialiser à ce jour mais ca me parait interessant, oui. Par curiosité, j'imagine que tu utilises la reflexion pour serialiser. Comment geres tu les references circulaires (typiquement, la liste chainee dans les deux sens) ?

  3. #3
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 326
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 326
    Billets dans le blog
    12
    Par défaut
    Oui, j'utilise la reflection. Pour le cas des formats fichier pas de souci, car les types acceptés sont basiques (des primitifs + wrapper, String et dates). Pour le format binaire comme Java c'est géré par la sérialisation Java. Pour les implémentations texte qui utilisent la librairie gson (pour le json) et jaxb (pour le xml) ce n'est pas géré il me semble.
    N'hésitez pas à consulter la FAQ Java, lire les cours et tutoriels Java, et à poser vos questions sur les forums d'entraide Java

    Ma page Developpez | Mon profil Linkedin | Vous souhaitez me contacter ? Contacter Gokan EKINCI

  4. #4
    Membre Expert

    Homme Profil pro
    Consultant informatique
    Inscrit en
    Janvier 2004
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 301
    Par défaut
    Tu dois implémenter une interface spécifique pour être sérializable avec ton api? donc je dois me coupler fortement à ta lib, et je ne peux rien sérialiser si je n'ai pas accès au code source de l'objet en question (genre un objet hérité d'une api sur lesquelles je n'ai aucun contrôle)... EDIT: ha non y'a pas d'interface spécifique, c'est cool

    Quel est l'avantage finalement, par rapport à la sérialisation standard de Java? J'imagine que pour produire une sortie binaire standard de mes objets, je dois implémenter ton interface + java.io.Serializable (sinon tu risques de prendre une NotSerializableException)? donc je dois respecter le contrat de serializable (implémenter Serializable, méthodes readResolve, champ serialVersionUid, etc...) donc pas de simplification de la sérialisation de ce côté

    Comment te protèges-tu contre les corruptions de flux. J'ai une classe qui détermine un invariant (genre dateDebut, dateFin, avec dateDebut<=dateFin). Si je bidouille les flux à la main, comment détectes-tu que la désérialisation doit échouer? PS: Serializable permet ça via les méthodes readObject/readResolve

    Comment adresses-tu les potentiels problèmes de compatibilité entre les versions d'une classe? Genre ma classe A en v1 n'avait pas de champ "int pouet", mais en version v2 oui: que se passe-t-il quand je désérialize un flux issu de la version 1 dans un classpath qui contient la version 2?

    Comment détermines-tu le type réel à créer? Je vois que tu passes des listes "List<MaClasse>", mes les génériques sont perdus à la compilation. Comment sais-tu que lors de la désérialisation, c'est des instances de MaClasse qu'il faut produire? Tu stockes l'information dans le flux? Dans le cas d'un fichier Excel, ça part où? EDIT: ok c'est en construisant le sérializeur, j'avais pas vu

    Pourquoi produis-tu des Path en sortie? Je n'ai aucun choix sur l'endroit où je veux stocker les infos?? Pour moi, un serialiseur doit lire/écrire des flux, pas référencer d'autres api. L'utilisateur s'occupe ensuite de brancher les flux sur ce qu'il veut (un FileIn/OutputStream, un socket.getIn/OutputStream, un ByteArrayIn/OutputStream pour avoir les données en mémoire, etc...)

    Et si tu ne résous pas la problématique des références circulaires, quel que soit le format utilisé, ça va vite perdre de son intérêt...

    Bref, pourquoi pas, mais je pense qu'il faudrait aller au fond de la réflexion pour être utilisable en prod...

  5. #5
    Membre Expert
    Inscrit en
    Mai 2006
    Messages
    1 364
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 1 364
    Par défaut
    Sauf erreur de ma part (j'ai regardé le code il y a quelques jours), il utilise writeObject donc il suffit d'implémenter java.io.Serializable (il n'y a pas une autre interface "custom" à implémenter).

    Par contre, je suis d'accord qu'il faudrait etre plus clair sur l'objectif du projet. Typiquement, si l'objectif est d'avoir un outil qui permet réellement de gérer la serialisation, je trouve aussi qu'il manque encore beaucoup de choses (pas de gestion de version de ce que j'ai vu, pas de gestion de references, ...).

    Mais si l'objectif est simplement de mettre à disposition un outil qui gere des besoins basiques, pourquoi pas ? Mais dans ce cas, ce serait bien de mieux cadrer ce qui est possible ou non.

  6. #6
    Modérateur
    Avatar de Gugelhupf
    Homme Profil pro
    Analyste Programmeur
    Inscrit en
    Décembre 2011
    Messages
    1 326
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste Programmeur

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 326
    Billets dans le blog
    12
    Par défaut
    Quel est l'avantage finalement, par rapport à la sérialisation standard de Java? J'imagine que pour produire une sortie binaire standard de mes objets, je dois implémenter ton interface + java.io.Serializable (sinon tu risques de prendre une NotSerializableException)? donc je dois respecter le contrat de serializable (implémenter Serializable, méthodes readResolve, champ serialVersionUid, etc...) donc pas de simplification de la sérialisation de ce côté
    L'avantage, c'est la simplicité à écrire le code, et aussi de ne pas avoir à oublier la fermeture du flux (dans le cas ci-dessous la fermeture n'est pas nécessaire avec ByteArrayOutputStream, mais pour d'autres implémentations ça peut l'être) :
    vanilla Java universal-serializer
    Code Java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    try (
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos)
    ) {
        oos.writeObject(objectToSerialize);
        byte[] byteArray = baos.toByteArray();
    } catch (IOException e) {
        // ...
    }
    Code Java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    try {
        JavaSerializer<MyClass> s = new JavaSerializer<>();
        byte[] byteArray = s.serialize(objectToSerialize);
    } catch (SerializationException e) {
        // ...
    }

    Tu n'es pas obligé d'implémenter Serializable sur ton type tant que ton implémentation le fait (ex: tu peux sérialiser une List tant que l'implémentation implémente Serializable, ex : ArrayList). C'est expliqué dans la JavaDoc de JavaSerializer. Il n'a jamais été obligatoire d'implémenter les méthodes readResolve ou champ serialVersionUid dans ton type pour faire de la sérialisation Java.


    Comment te protèges-tu contre les corruptions de flux. J'ai une classe qui détermine un invariant (genre dateDebut, dateFin, avec dateDebut<=dateFin). Si je bidouille les flux à la main, comment détectes-tu que la désérialisation doit échouer? PS: Serializable permet ça via les méthodes readObject/readResolve
    Comment adresses-tu les potentiels problèmes de compatibilité entre les versions d'une classe? Genre ma classe A en v1 n'avait pas de champ "int pouet", mais en version v2 oui: que se passe-t-il quand je désérialize un flux issu de la version 1 dans un classpath qui contient la version 2?
    J'utilise les librairies Java, donc c'est la JRE qui se charge de la corruption du flux ou des problèmes de version. Cela ne t'empêche de modifier les octets si tu connais le protocole de sérialisation Java et que tu sais exactement quelles valeurs tu veux modifier.

    Pourquoi produis-tu des Path en sortie? Je n'ai aucun choix sur l'endroit où je veux stocker les infos?? Pour moi, un serialiseur doit lire/écrire des flux, pas référencer d'autres api. L'utilisateur s'occupe ensuite de brancher les flux sur ce qu'il veut (un FileIn/OutputStream, un socket.getIn/OutputStream, un ByteArrayIn/OutputStream pour avoir les données en mémoire, etc...)
    Path est le type Java standard pour représenter le chemin d'un fichier, par défaut le fichier est créé en tant que temporaire, si tu souhaites modifier l'endroit où tu veux récupérer/stocker ton fichier il suffit de le renseigner dans l'objet FileOptions#destinationPath que tu placeras le constructeur des sérialiseurs fichier (c'est indiqué dans le README.md). Enfin si tu veux manipuler des flux, tu peux utiliser les méthodes sendTo() et receiveFrom()
    Et si tu ne résous pas la problématique des références circulaires, quel que soit le format utilisé, ça va vite perdre de son intérêt...
    J'ai créé un wrapper, je lègue les problématiques aux implémentations, dans le cas actuel à JAXB et Gson.


    je trouve aussi qu'il manque encore beaucoup de choses (pas de gestion de version de ce que j'ai vu, pas de gestion de references, ...)
    Pour avoir implémenté la sérialisation Java (création d'un bridge en C#), ou utilisé d'autres formats, la gestion de version n'a jamais été une obligation quelque soit le format utilisé. Qu'est-ce que la gestion de references ?


    Merci pour vos retours
    N'hésitez pas à consulter la FAQ Java, lire les cours et tutoriels Java, et à poser vos questions sur les forums d'entraide Java

    Ma page Developpez | Mon profil Linkedin | Vous souhaitez me contacter ? Contacter Gokan EKINCI

Discussions similaires

  1. [Projet] Mon projet domotique "wagoïd"
    Par alain1968 dans le forum Android
    Réponses: 3
    Dernier message: 15/10/2011, 19h40
  2. Réponses: 9
    Dernier message: 10/01/2007, 09h04

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo