Précédent   Forum des professionnels en informatique > Java > Général Java > APIs
APIs Forum sur les API standard et API complémentaires. Avant de poster -> FAQ Java, Les meilleures API Java
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 24/10/2006, 15h35   #1
Membre Expert
 
Avatar de narmataru
 
Inscription : décembre 2002
Messages : 1 423
Détails du profil
Informations personnelles :
Âge : 31
Localisation : France, Loire Atlantique (Pays de la Loire)

Informations forums :
Inscription : décembre 2002
Messages : 1 423
Points : 1 491
Points : 1 491
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 :
1
2
 
Liste<Class> monType = ClassUtilitie.findSubClass(mon.package.MonInterface.class);
merci
__________________
Reportage d'Arte sur Linux
narmataru est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/10/2006, 15h53   #2
Rédacteur/Modérateur
 
Avatar de adiGuba
 
Homme
Développeur Java/Web
Inscription : avril 2002
Messages : 12 460
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Corse (Corse)

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

Informations forums :
Inscription : avril 2002
Messages : 12 460
Points : 19 447
Points : 19 447
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++
__________________
adiGuba [ tutoriels | blog | twitter ] Rédacteur/Modérateur Java Présentation de Java SE 7 (commentaires)
adiGuba est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/10/2006, 16h25   #3
Membre Expert
 
Avatar de narmataru
 
Inscription : décembre 2002
Messages : 1 423
Détails du profil
Informations personnelles :
Âge : 31
Localisation : France, Loire Atlantique (Pays de la Loire)

Informations forums :
Inscription : décembre 2002
Messages : 1 423
Points : 1 491
Points : 1 491
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
__________________
Reportage d'Arte sur Linux
narmataru est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/10/2006, 16h51   #4
Rédacteur/Modérateur
 
Avatar de adiGuba
 
Homme
Développeur Java/Web
Inscription : avril 2002
Messages : 12 460
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Corse (Corse)

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

Informations forums :
Inscription : avril 2002
Messages : 12 460
Points : 19 447
Points : 19 447
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 :
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 :
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++
__________________
adiGuba [ tutoriels | blog | twitter ] Rédacteur/Modérateur Java Présentation de Java SE 7 (commentaires)
adiGuba est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/10/2006, 17h00   #5
Membre Expert
 
Avatar de narmataru
 
Inscription : décembre 2002
Messages : 1 423
Détails du profil
Informations personnelles :
Âge : 31
Localisation : France, Loire Atlantique (Pays de la Loire)

Informations forums :
Inscription : décembre 2002
Messages : 1 423
Points : 1 491
Points : 1 491
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
__________________
Reportage d'Arte sur Linux
narmataru est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/10/2006, 17h35   #6
Rédacteur/Modérateur
 
Avatar de adiGuba
 
Homme
Développeur Java/Web
Inscription : avril 2002
Messages : 12 460
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Corse (Corse)

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

Informations forums :
Inscription : avril 2002
Messages : 12 460
Points : 19 447
Points : 19 447
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 :
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++
__________________
adiGuba [ tutoriels | blog | twitter ] Rédacteur/Modérateur Java Présentation de Java SE 7 (commentaires)
adiGuba est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/10/2006, 10h02   #7
Membre Expert
 
Avatar de narmataru
 
Inscription : décembre 2002
Messages : 1 423
Détails du profil
Informations personnelles :
Âge : 31
Localisation : France, Loire Atlantique (Pays de la Loire)

Informations forums :
Inscription : décembre 2002
Messages : 1 423
Points : 1 491
Points : 1 491
Ouha un grand merci, je vais regarder et tester tout ça
__________________
Reportage d'Arte sur Linux
narmataru est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 25/10/2006, 11h00   #8
Membre Expert
 
Avatar de narmataru
 
Inscription : décembre 2002
Messages : 1 423
Détails du profil
Informations personnelles :
Âge : 31
Localisation : France, Loire Atlantique (Pays de la Loire)

Informations forums :
Inscription : décembre 2002
Messages : 1 423
Points : 1 491
Points : 1 491
Merci beaucoup adiGuba ça fonctionne
__________________
Reportage d'Arte sur Linux
narmataru est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 06h44.


 
 
 
 
Partenaires

Hébergement Web