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 :

[REFLEXION] Connaitre toutes les classes qui implémentent une interface


Sujet :

API standards et tierces Java

  1. #1
    Membre expérimenté
    Avatar de narmataru
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    1 548
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 1 548
    Points : 1 680
    Points
    1 680
    Par défaut [REFLEXION] Connaitre toutes les classes qui implémentent une interface
    Bonjour,
    Quel est selon vous le meilleur moyen de trouver l'ensemble des class implémentant une interface ?
    La seule chose connu serait que ces classe se trouvent dans un package bien spécique.

    Voici un peu ce que je cherche à faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Liste<Class> monType = ClassUtilitie.findSubClass(mon.package.MonInterface.class);
    merci

  2. #2
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,


    Il n'y a aucun moyen de faire cela via la reflection : ce serait bien trop lourd car il faudrait charger toutes les classes du CLASSPATH...

    Si ces classes ne sont présente que dans un seul et unique package à la rigueur tu pourrais faire cela "à la main" en chargeant les classes une à une mais ce n'est pas pratique (on ne peut même pas connaitre toutes les classes d'un même package).


    Pourquoi as-tu besoin de cela ?

    a++

  3. #3
    Membre expérimenté
    Avatar de narmataru
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    1 548
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 1 548
    Points : 1 680
    Points
    1 680
    Par défaut
    Merci,
    J'ai déjà fait ce genre de chose. En fait je parcourais tous les fichier classe d'un répertoire, je chargeait la classe puis je vérifiait qu'elle implémentaient la classe mère. Ca fonctionne mais mon code n'est pas top je trouve et dans certains cas ça ne fonctionne pas.

    J'utilise ce chargement dynamique pour avoir un système de plugin dans mon application. J'aurais espéré que les nouvelles version de java me facilite la tâche

  4. #4
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Avec Java 6 il y a la notion de service qui pourrait être une aternative au scan des répertoires...


    Un "service" correspond à une interface (ou une classe abstraite), et les "service provider" sont des implémentations de cette interface (ou de cette classe abstraite).

    Toutes les implémentations doivent être déclarées dans un fichier spécifique dans le répertoire META-INF/services...

    A partir de là, la classe ServiceLoader peut te retrouver toutes les implémentation ainsi déclarées...


    Par exemple, tu as une interface com.maboite.MonInterface, et trois implémentation spécifique com.maboite.MonImpl, com.monautreboite.MaClasse et com.monautreboite.souspackage.MonAutreImpl

    Tu devras donc avoir un fichier META-INF/services/com.maboite.MonInterface qui contiendra les lignes suivantes :
    Code X : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    com.maboite.MonImpl
     com.monautreboite.MaClasse
    com.monautreboite.souspackage.MonAutreImpl


    Ensuite, il ne te reste plus qu'à utiliser la méthode load() qui analysera ce fichier et chargera ces classes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for (MonInterface interface : ServiceLoader.load(MontInterface.class)) {
         ...
    }

    Bien sûr chacun de tes jar ou de tes répertoires du classpath peuvent avoir un de ces fichiers, et ils seront tous lus...


    Tu ne dois surement pas utiliser Java 6 mais ce n'est pas vraiment très compliqué à codé : il suffit d'utiliser la méthode getResources(java.lang.String) du ClassLoader pour retrouver tous les fichiers du même nom dans les divers éléments du classpath...

    ensuite ce n'est que lecture de fichier + reflection simple...


    Je dois avoir un code de ce genre quelque part... si je le retrouve je le posterais...

    a++

  5. #5
    Membre expérimenté
    Avatar de narmataru
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    1 548
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 1 548
    Points : 1 680
    Points
    1 680
    Par défaut
    Ca a l'aire trop fort cette histoire de service ! Il sort quand Java6 ?
    Si je comprend bien il va falloire que je parcours encore mes pakages et faire tout ça à la mimine....

    merci adiGuba

  6. #6
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par narmataru
    Ca a l'aire trop fort cette histoire de service ! Il sort quand Java6 ?
    Il devrait sortir d'ici la fin de l'année...


    Citation Envoyé par narmataru
    Si je comprend bien il va falloire que je parcours encore mes pakages et faire tout ça à la mimine....
    Non tu peux très bien coder cela : ce n'est pas bien compliquée...

    Cela pourrait donner ceci (code Java 5.0 à adapter au cas où) :
    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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
        public static <T> Iterable<Class<? extends T>> searchServices(Class<T> abstractType, ClassLoader loader) throws IOException, ClassNotFoundException, ClassCastException {
     
            // Nom des fichiers contenants les "services" :
            String name = "META-INF/services/" + abstractType.getName();
     
            // Liste contenant le résultat
            Set<Class<? extends T>> resultSet = new HashSet<Class<? extends T>>();
     
            // Pattern permettant de supprimer les commentaires :
            Pattern pattern = Pattern.compile("#.*$");
     
     
            // On parcours la liste des fichiers 'services' :
            Enumeration<URL> resources = loader.getResources(name);
            while (resources.hasMoreElements()) {
                URL url = resources.nextElement();
     
                // On lit le fichier ligne par ligne
                BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream(), "UTF-8"));
                try {
                    String line;
                    while ( (line=reader.readLine()) != null ) {
                        // On supprime tout ce qui suit le # (commentaire)
                        line = pattern.matcher(line).replaceAll("").trim();
                        if (!"".equals(line)) {
                            // On charge la classe :
                            Class<?> classType = loader.loadClass(line);
     
                            // Et on l'ajoute dans la liste des résultats
                            // (ClassCastException en cas de type incorrect)
                            resultSet.add( classType.asSubclass(abstractType) );
                        }
                    }
                } finally {
                    reader.close();
                }
            }
     
            return resultSet;
        }
    Note : en cas d'erreur l'exception est remonté à la méthode appellante. Il serait surement utile d'adapter cela pour éviter ce type de problème

    a++

  7. #7
    Membre expérimenté
    Avatar de narmataru
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    1 548
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 1 548
    Points : 1 680
    Points
    1 680
    Par défaut
    Ouha un grand merci, je vais regarder et tester tout ça

  8. #8
    Membre expérimenté
    Avatar de narmataru
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    1 548
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Décembre 2002
    Messages : 1 548
    Points : 1 680
    Points
    1 680
    Par défaut
    Merci beaucoup adiGuba ça fonctionne

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

Discussions similaires

  1. Réponses: 142
    Dernier message: 02/04/2010, 19h50
  2. Réponses: 8
    Dernier message: 07/06/2009, 20h31
  3. Connaitre toutes les instances d'une classe
    Par miniseb dans le forum Langage
    Réponses: 14
    Dernier message: 09/01/2006, 17h35
  4. Réponses: 2
    Dernier message: 17/06/2005, 23h03
  5. [Reflection] Obtenir toutes les classes implémentant une interface
    Par Pill_S dans le forum API standards et tierces
    Réponses: 4
    Dernier message: 20/04/2005, 16h48

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