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

API standards et tierces Java Discussion :

API XStream ajout de classe


Sujet :

API standards et tierces Java

  1. #1
    Membre éclairé
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mai 2006
    Messages
    350
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2006
    Messages : 350
    Par défaut API XStream ajout de classe
    Bonjours,

    Nous utilisons une sérialisation automatique a partir de l'API XStream.

    Nous avons donc notre plugin (eclispe) qui sérialise et dé-sérialise automatiquement nos objets.

    Maintenant, j'ai ajouté un point d'extension, qui rajoute des objets en plus. Le problème est qu'a la dé-sérialisation, il ne semble plus connaitre les objets qui sont issus du plugin.

    Je souhaiterais bien lui ajouter les classes qui ne connaient pas, mais je ne sais pas ou les ajouter.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    	public static List<Resource> deserializeObject(final String xmlFilePath) {
    		List<Resource> deserializedObject = null;
     
    		try {
    			// Instanciation de la classe XStream
    			XStream xstream = new XStream(new DomDriver(ENCODAGE));
    			ClassLoader classLoader = Activator.class.getClassLoader();
    			xstream.setClassLoader(classLoader);
     
    			// Redirection du fichier vers un flux d'entrée fichier
    			FileInputStream fis = new FileInputStream(new File(xmlFilePath));
     
    			try {
    				// Désérialisation du fichier vers un nouvel objet
    				deserializedObject = (List<Resource>) xstream.fromXML(fis);
    			} finally {
    				// On s'assure de fermer le flux quoi qu'il arrive
    				fis.close();
    				fis = null;
    				System.gc();
    			}
    		} catch (FileNotFoundException e) {
    			e.printStackTrace();
    		} catch (IOException ioe) {
    			ioe.printStackTrace();
    		}
    		return deserializedObject;
    	}
    Sur mon gestionnaire de point d'extension, j'ai ajouté la méthode qui parcours toutes les extensions et qui récupère les classes utiles.

    Mais maintenant, j'en fait quoi ?

    Merci d'avance.

  2. #2
    Membre éclairé
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mai 2006
    Messages
    350
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2006
    Messages : 350
    Par défaut
    Personne ne sait comment contourner le problème ?

    L'exception exacte est : "com.thoughtworks.xstream.mapper.CannotResolveClassException" sur l'object de ma classe qui est dans le plugin.

  3. #3
    ego
    ego est déconnecté
    Rédacteur

    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Juillet 2004
    Messages
    1 883
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Architecte de système d'information
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 883
    Billets dans le blog
    2
    Par défaut
    je ne sais pas si c'est faisable dans ton contexte mais si tu essayes d'ajouter l'appel à xstream.processAnnotations(...)pour tes nouvelles classes "inconnues", ceci avant le "read"

  4. #4
    Membre éclairé
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mai 2006
    Messages
    350
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2006
    Messages : 350
    Par défaut
    Bonsoir,

    Aucun changement.
    Maintenant, je ne sais pas si ca lui change quelque chose !! J'arrive pas a m'y retrouver dans l'objet XStream.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    ---- Debugging information ----
    message             : fr.projet.sourceExtractor.model.GdalAcquisitionSource : fr.projet.sourceExtractor.model.GdalAcquisitionSource
    cause-exception     : com.thoughtworks.xstream.mapper.CannotResolveClassException
    cause-message       : fr.projet.sourceExtractor.model.GdalAcquisitionSource : fr.projet.sourceExtractor.model.GdalAcquisitionSource
    class               : java.util.ArrayList
    required-type       : java.util.ArrayList
    path                : /list/fr.projet.sourceExtractor.model.GdalAcquisitionSource
    -------------------------------
     com.thoughtworks.xstream.converters.ConversionException: fr.projet.sourceExtractor.model.GdalAcquisitionSource : fr.projet.sourceExtractor.model.GdalAcquisitionSource : fr.projet.sourceExtractor.model.GdalAcquisitionSource : fr.projet.sourceExtractor.model.GdalAcquisitionSource
    ---- Debugging information ----
    message             : fr.projet.sourceExtractor.model.GdalAcquisitionSource : fr.projet.sourceExtractor.model.GdalAcquisitionSource
    cause-exception     : com.thoughtworks.xstream.mapper.CannotResolveClassException
    cause-message       : fr.projet.sourceExtractor.model.GdalAcquisitionSource : fr.projet.sourceExtractor.model.GdalAcquisitionSource
    class               : java.util.ArrayList
    required-type       : java.util.ArrayList
    path                : /list/fr.projet.sourceExtractor.model.GdalAcquisitionSource
    -------------------------------
    Voici exactement la trace que j'ai.

  5. #5
    Membre éclairé
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mai 2006
    Messages
    350
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2006
    Messages : 350
    Par défaut
    Et sinon, l'idée de créer un ClassLoader a partir de plusieurs ClassLoader, c'est pas possible ?

  6. #6
    ego
    ego est déconnecté
    Rédacteur

    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Juillet 2004
    Messages
    1 883
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Architecte de système d'information
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 883
    Billets dans le blog
    2
    Par défaut
    Pourrais-tu être plus précis sur ton point d'extension et comment tu le gères dans ton plugin (celui qui déclare le point d'extension) ?

    Si dans un point d'extension on manipule une classe inconnue, on a en général un bout de code comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for (IConfigurationElement e : config) {
      final Object o = e.createExecutableExtension("class");
    class est un attribut d'un tag XML du point d'extension qui déclare une classe.

    En récupérant l'objet o, ne peux tu pas faire un truc comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    xstream.processAnnotations(o.getClass());
    NB : re-montres le code que tu as au niveau de la lecture du XML avec xstream

  7. #7
    Membre éclairé
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mai 2006
    Messages
    350
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2006
    Messages : 350
    Par défaut
    Oui effectivement, j'ai ca :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    	private void initialiseManager() {
    		acqFactories = new ArrayList<AbstractAcquisitionFactory>();
     
    		IConfigurationElement[] contributions = Platform.getExtensionRegistry().getConfigurationElementsFor(
    		        EXTENSION_POINT_ID);
     
    		for (IConfigurationElement contribution : contributions) {
    			try {
    				// Récupération de la factory
    				Object obj = contribution.createExecutableExtension("factory");
    				AbstractAcquisitionFactory factory = (AbstractAcquisitionFactory) obj;
     
    				// TODO ajout de la condition d'utilisation si nécessaire
    				acqFactories.add(factory);
     
    			} catch (CoreException e) {
    				logger.error("Impossible d'utiliser le plugins");
    			}
    		}
    	}
    Après, dans mon interface, j'ai défini une méthode qui me retourne les object. Mais l'ajout dans le XStream par la méthode processAnnotations ne change rien.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
     
    	public void addClass(final XStream xstream) {
    		ClassLoader classLoader = xstream.getClassLoader();
     
    		if (acqFactories != null) {
    			for (AbstractAcquisitionFactory acqFactory : acqFactories) {
    				System.out.println("acqfactory " + acqFactory);
     
    				List<Class> classes = acqFactory.getClassForSerialization();
    				if (classes != null) {
    					for (Class class1 : classes) {
    						System.out.println("class : " + class1);
    						xstream.processAnnotations(class1);
    					}
    				}
    			}
    		}
    	}

  8. #8
    ego
    ego est déconnecté
    Rédacteur

    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Juillet 2004
    Messages
    1 883
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Architecte de système d'information
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 883
    Billets dans le blog
    2
    Par défaut
    m...de alors !
    bon, il faudrait que je fasse un plugin comme toi pour tester mais là va falloir attendre...fêtes obligent

    je reste sur le coup quand même car le sujet m'intéresse

  9. #9
    Membre éclairé
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mai 2006
    Messages
    350
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2006
    Messages : 350
    Par défaut
    Oki ben merci !!
    Et bonne fête alors ^^

  10. #10
    ego
    ego est déconnecté
    Rédacteur

    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Juillet 2004
    Messages
    1 883
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Architecte de système d'information
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 883
    Billets dans le blog
    2
    Par défaut
    bon j'ai trouvé une solution
    regardes les projets dans le .zip en pièce jointe

    xstream-reference possède une extension. Cette extension permet de charger une "factory" qui va créer des objets. Dans ce projet, j'ai un objet RootXML qui contient une liste d'objets (Object). Ces objets sont créés via l'appel à la factory, factory fournie par le second plugin xstream-contributor. Les classes créées sont Client et Command.

    Au début, j'avais les mêmes problèmes que toi.

    J'ai utilisé la classe DynamicClassLoader du projet Sling. J'ai trouvé ça dans des discussions sur le web. (http://web.archiveorange.com/archive...CqEWrSiEAj2MsS)

    La fin de cette discussion parle d'une autre manière de faire mais je n'ai pas tout compris et pas essayé.

    Dans le zip il n'y a pas les .jar nécessaires qui sont utilisés dans les "lib" des 2 projets. Les .jar à mettre sont dans les images .png en pièce jointe
    Images attachées Images attachées   
    Fichiers attachés Fichiers attachés

  11. #11
    Membre éclairé
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mai 2006
    Messages
    350
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2006
    Messages : 350
    Par défaut
    Je teste ca dessuite.

    Je me suis essayé a formaliser le problème sur le projet de mail eclipse.
    J'ai mis le zip ici : croc14.free.fr/mailboxExemple.zip

    Il s'agit du projet MailBox de eclipse + 2 projets qui étende le point d'extension.
    Au démarrage d' l'appli, on charge un fichier XML. A la fermeture on sauvegarde les mails ouverts.

    Pour créer un nouveau mail, il doit y avoir dans nouveau 3 action :
    - defaut mail
    - rss mail
    - crypted mail

    Merci pour ton aide.

  12. #12
    Membre éclairé
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mai 2006
    Messages
    350
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2006
    Messages : 350
    Par défaut
    Salut et Bonne année,

    Après intégration dans le projet, je viens de comprendre ce qu'ils sous entendent par DynamicClassLoader.
    En fait il s'agit bien d'un classLoader qui charge le classloader d'un sous plugin mais qui peut en recharger un nouveau a tous moments.

    Ce qui explique le :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    				for (IConfigurationElement e : config) {
    					final Object o = e.createExecutableExtension("factory");
    					if (o instanceof IMailboxFactory) {
    						this.factory = (IMailboxFactory) o;
    					}
    				}
    Je trouvais ca bizarre que pour les X plugin connecté, on ne conserve que le dernier.

    Ce qu'il me faut, c'est d'avoir tous les ClassLoader de charger dans un seul.
    Je continu l'investigation.

    @+

  13. #13
    ego
    ego est déconnecté
    Rédacteur

    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Juillet 2004
    Messages
    1 883
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Architecte de système d'information
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 883
    Billets dans le blog
    2
    Par défaut
    Mais mon truc ne te vas pas ?
    Dans mon cas, les classes créées par le second plugin ne sont pas connues, du tout, par le premier

  14. #14
    Membre éclairé
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mai 2006
    Messages
    350
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2006
    Messages : 350
    Par défaut
    Bon ben je m'auto répond.

    En lisant un article sur l'ajout de class disponible sur des serveurs, j'ai vu qu'il était possible de charger une classe a part.
    Mais plutôt que de la créer, dans mon cas, il suffit de la chercher dans une liste de ClassLoader.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    		ArrayList<Class> classes = new ArrayList<Class>();
     
    		if (classLoaderList != null) {
    			for (ClassLoader classloader : classLoaderList) {
    				try {
    					Class findedClass = classloader.loadClass(name);
    					if ((findedClass != null) && (!classes.contains(findedClass))) {
    						classes.add(findedClass);
    					}
    				} catch (Exception e) {
    				}
    			}
    		}
     
    		if (classes.isEmpty()) {
    			throw new ClassNotFoundException("Aucun classloader ne contient " + name);
    		} else if (classes.size() != 1) {
    			throw new ClassNotFoundException("Plusieurs classloaders ne contiennent " + name);
    		} else {
    			return classes.get(0);
    		}
    Au niveau de la déclaration du MultiClassLoader, j'ai choisi de la faire au moment de l'initialisation des mes Plugins connectés :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    		mailboxFactories = new ArrayList<IMailboxFactory>();
    		classLoader = new MultiClassLoader(Activator.getDefault().getClass()
    				.getClassLoader());
     
    		IConfigurationElement[] contributions = Platform.getExtensionRegistry()
    				.getConfigurationElementsFor(EXTENSION_ID);
     
    		for (IConfigurationElement contribution : contributions) {
    			try {
    				// Récupération de la factory
    				Object obj = contribution.createExecutableExtension("factory");
    				IMailboxFactory factory = (IMailboxFactory) obj;
     
    				mailboxFactories.add(factory);
    				classLoader.addClassLoader(factory.getClass().getClassLoader());
     
    			} catch (CoreException e) {
    				System.err.println("Impossible d'utiliser le plugins");
    			}
    		}
    Je confirme le fonctionnement sur le vrai projet. Mais il ne devrait pas y avoir de problème.

    Maintenant, j'ai une question. J'ai essayé de gérer le fait qu'une classe soit défini dans plusieurs classLoader.
    Si réellement il s'agit de la même classe (import d'une classe commune entre deux plugins) est ce que le contains le détectera ?

    Encore merci de votre aide.

    @+

  15. #15
    Membre éclairé
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mai 2006
    Messages
    350
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2006
    Messages : 350
    Par défaut
    Citation Envoyé par ego Voir le message
    Mais mon truc ne te vas pas ?
    Dans mon cas, les classes créées par le second plugin ne sont pas connues, du tout, par le premier
    Désolé, du croisement.
    Si, mais je ne peut avoir qu'un seul plugin annexe.
    Il fallait vraiment pouvoir avoir tous les classloaders connus.

    Et il me semble que ta solution ne le permettait pas.

    Encore merci.

  16. #16
    Membre éclairé
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mai 2006
    Messages
    350
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2006
    Messages : 350
    Par défaut
    Je viens d'intégrer le MultiClassLoader dans mon projet.

    Donc ca marche.
    En revenche, une autre solution était de ne pas définir de classLoader a XStream mais d'utiliser un : DynamicImport-Package: *

    La solution du dynamic import fonctionne très bien sur le projet test SerializedMail.
    Mais il ne marche pas sur mon projet boulot. Surement des conflits avec les import/export.

    Donc deux solution :
    - MultiClassLoader
    - Dynamic-Import:*

    Merci de votre aide.

    Résolu

  17. #17
    ego
    ego est déconnecté
    Rédacteur

    Homme Profil pro
    Architecte de système d'information
    Inscrit en
    Juillet 2004
    Messages
    1 883
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Architecte de système d'information
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2004
    Messages : 1 883
    Billets dans le blog
    2
    Par défaut
    Pour l'existence de la classe dans plusieurs classloader, je ne sais pas trop ce qui va se passer. En effet, OSGI permet le chargement de plusieurs versions d'un même plugin. Quid de ta recherche via le nom de la classe ? Est-il possible de récupérer des fois une classe depuis le plugin-v1 et d'autres fois une classe (avec le même nom) depuis le plugin-v2 ?
    Là je ne sais pas et il faudrait essayer

    Le Dynamic-import ne doit fonctionner qu'à partir du moment où les classes recherchées sont exportées par le plugin où elles sont définies

    Mais bon si tu as trouvé une solution, c'est le principal

  18. #18
    Membre éclairé
    Homme Profil pro
    Développeur Java
    Inscrit en
    Mai 2006
    Messages
    350
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2006
    Messages : 350
    Par défaut
    Oké.

    Encore merci de ton aide.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. ajouter des classes à une app déployée
    Par barhili04 dans le forum C#
    Réponses: 4
    Dernier message: 25/05/2007, 13h57
  2. ajouter une classe dans un projet
    Par bonbino dans le forum C++Builder
    Réponses: 4
    Dernier message: 23/10/2006, 15h35
  3. Ajouter une class CSS a une nouvelle cellule
    Par Arfigado dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 26/09/2006, 11h08
  4. [debutant] Comment ajouter des .class ?
    Par Slein dans le forum Eclipse Java
    Réponses: 3
    Dernier message: 30/04/2004, 15h30

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