Introspection : comment trouver toutes les classes filles ?

Introspection : comment trouver toutes les classes filles ? - Java - Programmation

Marsh Posté le 15-11-2005 à 17:38:22    

Bonjour,
 
Grâce à l'introspection, j'ai découvert qu'il était très facile de retrouver de manière dynamique la classe mère d'une classe en utilisant la classe Class.
 
Peut-on faire l'inverse ? C'est à dire, étant donné une classe, retrouver toutes ses classes filles ? Et si oui, comment ?
 
Merci.

Reply

Marsh Posté le 15-11-2005 à 17:38:22   

Reply

Marsh Posté le 15-11-2005 à 17:45:44    

non. les classes sont chargées à la demande.
si charger une classe nécessite de charger toutes ses parentes, elle ne dit rien sur ses filles. Sinon, on serait obligé de tout charger tout le temps.


---------------
trainoo.com, c'est fini
Reply

Marsh Posté le 15-11-2005 à 22:47:06    

Merci pour la réponse.
 
Il ne me reste plus qu'à pleurer...  :cry:  

Reply

Marsh Posté le 16-11-2005 à 15:04:37    

Tu voudrais faire quoi, exactement ?

Reply

Marsh Posté le 24-11-2005 à 17:05:19    

Regarde la méthode getSubClasses, cela te donnera sans doute des idées :
http://www.johnspurlock.com/projec [...] Utils.java
 
La javadoc génère aussi les classes dérivées.

Reply

Marsh Posté le 25-11-2005 à 03:36:24    

tain mais il aurait pas encore pu en mettre plus de ses merdes, dans cte classe? [:x-httpd-php]
un php'eux qui s'est perdu ou quoi ?


Message édité par the real moins moins le 25-11-2005 à 03:40:20

---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 25-11-2005 à 07:39:49    

Si tu veux vraiment utiliser la réflexivité à fond, tu peux toujours utiliser un API réflexif pour java tel que Javassist et openJava.  Pour offrir davantage de possibilités (métaclasses, métaobjets, etc.), ces api reflexifs (1) remplacent la machine virtuelle par une trafiquée ou (2) remplacent le class loader ou (3) utilisent un préprocesseur.
 
Toutefois, à moins que tu en aille vraiment besoin, je ne pense pas que tu devrais utiliser ces outils, car ça implique beaucoup de choses (restreint la portabilité du code...).

Reply

Marsh Posté le 25-11-2005 à 10:04:29    

Sinon j'ai sous le coude une classe qui me permet de trouver toutes les classes filles d'une classe.
Je m'en sers pour faire des plugins.


---------------
get amaroK plugin
Reply

Marsh Posté le 25-11-2005 à 10:05:39    

yes, loadage de toutes les classes du classpath pour rien, et zappage total des autres classloaders, je présume? [:marc]


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 25-11-2005 à 10:05:53    

(fais peter)


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 25-11-2005 à 10:05:53   

Reply

Marsh Posté le 25-11-2005 à 10:15:04    

[:cupra]

Reply

Marsh Posté le 25-11-2005 à 10:15:46    

Comme marqué en commentaire, je me suis inspiré de http://java.developpez.com/sources [...] rs#plugins
 

Code :
  1. package fr.cemagref.modulesloader;
  2. import java.io.File;
  3. import java.io.FileFilter;
  4. import java.io.IOException;
  5. import java.lang.reflect.Modifier;
  6. import java.net.URL;
  7. import java.util.ArrayList;
  8. import java.util.Collection;
  9. import java.util.Enumeration;
  10. import java.util.List;
  11. import java.util.zip.ZipEntry;
  12. import java.util.zip.ZipFile;
  13. /**
  14. * <code>ModulesLoader</code> Load modules available in class path.  
  15. *  
  16. * @author Nicolas Dumoulin <nicolas.dumoulinATclermont.cemagref.fr>
  17. *  
  18. * @see http://java.developpez.com/sources [...] rs#plugins
  19. */
  20. public class ModulesLoader {
  21.     // Singleton
  22.     private static ModulesLoader instance = new ModulesLoader();
  23.     private List<String> modulesPackages = new ArrayList<String>();
  24.     /**
  25.      * <code>filter</code> accept directory and *.class (without $)
  26.      */
  27.     private static final FileFilter filter = new FileFilter() {
  28.         public boolean accept(File pathname) {
  29.             // Accept directory
  30.             if (pathname.isDirectory())
  31.                 return true;
  32.             // But nothing else that regular file
  33.             if (!pathname.isFile())
  34.                 return false;
  35.             // File must have ".class" extension
  36.             String path = pathname.getAbsolutePath();
  37.             if (!path.endsWith(".class" ))
  38.                 return false;
  39.             // And not contain a "$", so plugin defined as inner class are not
  40.             // permitted
  41.             if (path.indexOf('$') >= 0)
  42.                 return false;
  43.             return true;
  44.         }
  45.     };
  46.     private ModulesLoader() {}
  47.    
  48.     public ModulesLoader getInstance() {
  49.         return instance;
  50.     }
  51.    
  52.     /**
  53.      * @see java.util.List#add(E)
  54.      */
  55.     public static boolean addModulesPackage(String s) {
  56.         return instance.modulesPackages.add(s);
  57.     }
  58.     /**
  59.      * @see java.util.List#remove(java.lang.Object)
  60.      */
  61.     public static boolean removeModulesPackage(String s) {
  62.         return instance.modulesPackages.remove(s);
  63.     }
  64.     /**
  65.      * @return Returns the plugins list.
  66.      */
  67.     public static final Collection<Class> getPlugins(Class pluginSuperClass) throws IOException {
  68.         assert pluginSuperClass != null;
  69.         Collection<Class> plugins = new ArrayList<Class>();
  70.         String pluginHomeResource,pluginFileName;
  71.         for (String packageName : instance.modulesPackages) {
  72.             pluginHomeResource = packageName.replace('.', '/');
  73.             pluginFileName = packageName.replace('.', File.separatorChar);
  74.             plugins.addAll(instance.analyze(pluginSuperClass,pluginHomeResource,pluginFileName));
  75.         }
  76.         return plugins;
  77.     }
  78.     /**
  79.      * <code>analyze</code> Search modules available.
  80.      * @throws IOException If I/O errors occur @see java.lang.ClassLoader#getResources(java.lang.String)
  81.      */
  82.     private Collection<Class> analyze(Class pluginSuperClass,String pluginHomeResource, String pluginFileName) throws IOException {
  83.         Collection<Class> plugins = new ArrayList<Class>();
  84.         // fetchs list of directories that provides ressources under package pluginHomeResource
  85.         Enumeration e = this.getClass().getClassLoader().getResources(pluginHomeResource);
  86.         // analyze each directory and jar archive in this list
  87.         while (e.hasMoreElements()) {
  88.             URL url = (URL) e.nextElement();
  89.             String protocol = url.getProtocol();
  90.             if (protocol.equals("file" ))
  91.                 plugins.addAll(analyzeFromDirectory(new File(url.getFile().replace("%20", " " )), pluginSuperClass, pluginFileName));
  92.             else if (protocol.equals("jar" ))
  93.                 plugins.addAll(analyzeFromJar(url,pluginSuperClass,pluginHomeResource));
  94.         }
  95.         return plugins;
  96.     }
  97.    /**
  98.      * <code>analyzeFromDirectory</code> Analyze a directory.
  99.      *
  100.      * @param directory is the base directory to analyze
  101.      */
  102.     private Collection<Class> analyzeFromDirectory(File directory, Class pluginSuperClass, String pluginFileName) {
  103.         Collection<Class> plugins = new ArrayList<Class>();
  104.         Class classBuff;
  105.         boolean instanciable;
  106.         if (!directory.isDirectory())
  107.             return plugins;
  108.         // for each element in current directory
  109.         for (File file : directory.listFiles(ModulesLoader.filter)) {
  110.             if (file.isDirectory()) {
  111.                 // analyze recursively sub-directory
  112.                 plugins.addAll(analyzeFromDirectory(file,pluginSuperClass,pluginFileName));
  113.             } else {
  114.                 classBuff = null;
  115.                 // Convert file path to package path
  116.                 String name = file.getAbsolutePath();
  117.                 int pos = name.indexOf(pluginFileName);
  118.                 // Checks that file is in a subdirectory of base package => suposed true
  119.                 assert pos >= 0;
  120.                 name = name.replace(File.separatorChar, '.').substring(pos);
  121.                 classBuff = analyseClassFile(name,pluginSuperClass);
  122.                 if (classBuff!=null) {
  123.                     plugins.add(analyseClassFile(name,pluginSuperClass));
  124.                 }
  125.             }
  126.         }
  127.         return plugins;
  128.     }
  129.     /**
  130.      * <code>analyzeFromJar</code> Analyze a JAR archive  
  131.      *
  132.      * @param url The jar file to analyze
  133.      */
  134.     private Collection<Class> analyzeFromJar(URL url, Class pluginSuperClass,String pluginHomeResource) {
  135.         Collection<Class> plugins = new ArrayList<Class>();
  136.         String jarName = url.getFile();
  137.         jarName = jarName.substring(jarName.indexOf(':'));
  138.         jarName = jarName.substring(0, jarName.indexOf('!'));
  139.         jarName = jarName.replace('/', File.separatorChar);
  140.         try {
  141.             ZipFile zipFile = new ZipFile(jarName);
  142.             for (Enumeration<? extends ZipEntry> e = zipFile.entries();e.hasMoreElements();) {
  143.                 ZipEntry entry = e.nextElement();
  144.                 String name = entry.getName();
  145.                 if ((name.endsWith(".class" )) && (name.startsWith(pluginHomeResource)) && (name.indexOf('$') >= 0)) {
  146.                     name = name.replace('/', '.');
  147.                     plugins.add(analyseClassFile(name,pluginSuperClass));
  148.                 }
  149.             }
  150.             zipFile.close();
  151.         } catch (IOException e) {
  152.             assert false;
  153.             e.printStackTrace();
  154.         }
  155.         return plugins;
  156.     }
  157.    
  158.     private Class analyseClassFile(String name, Class pluginSuperClass) {
  159.         Class result = null;
  160.         // remove .class extension
  161.         name = name.substring(0, name.length() - 6);
  162.         // Convert file to Class
  163.         try {
  164.             Class plugin = Class.forName(name);
  165.             // Checks if it's a sub-class of the plugins super-class
  166.             if (pluginSuperClass.isAssignableFrom(plugin)) {
  167.                 // checks it isn't an abstract class
  168.                 if ((!plugin.isInterface())&&(!Modifier.isAbstract(plugin.getModifiers())))
  169.                     // add to the list of plugins
  170.                     result = plugin;
  171.             }
  172.         } catch (ClassNotFoundException e) {
  173.             // if file to Class conversion fails
  174.             System.err.println("file to Class conversion fails while dpugins loading" );
  175.             e.printStackTrace();
  176.         }
  177.         return result;
  178.     }
  179.  
  180. }


Message édité par bobuse le 25-11-2005 à 10:36:46

---------------
get amaroK plugin
Reply

Marsh Posté le 25-11-2005 à 10:16:55    

the real moins moins a écrit :

yes, loadage de toutes les classes du classpath pour rien, et zappage total des autres classloaders, je présume? [:marc]


pas trop compris, mais peut-être bien :D


---------------
get amaroK plugin
Reply

Marsh Posté le 25-11-2005 à 10:25:55    

       // TODO ? quoi servent ces 2 lignes
 
à recuperer le nom du jar depuis l'url d'une resource, qui ressemble à qqchose comme
file:///home/bobuse/pouet/tralala.jar!foo/bar/truc.properties


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 25-11-2005 à 10:27:21    

bobuse: faudrait ptet voir à utiliser un systeme de déclaration de plugins/services hein, plutot que d'aller à la peche aux canards sur le filesystem


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 25-11-2005 à 10:27:51    

(cfr avant-derniere page (je crois) sur le topic de l'élite du java mondial de besançon)


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 25-11-2005 à 10:35:47    

the real moins moins a écrit :

bobuse: faudrait ptet voir à utiliser un systeme de déclaration de plugins/services hein, plutot que d'aller à la peche aux canards sur le filesystem


 
oui d'accord, mais là c'est du quick and dirty hien !
Mais je note ...


---------------
get amaroK plugin
Reply

Marsh Posté le 25-11-2005 à 10:36:50    

euh, dirty oui, quick, par contre, je sais pas [:marc]


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 25-11-2005 à 10:39:04    

the real moins moins a écrit :

euh, dirty oui, quick, par contre, je sais pas [:marc]


pour l'écrire ? ha ba si, puisque j'ai pompé pas mal sur le source récupéré sur dev.com ;)


---------------
get amaroK plugin
Reply

Marsh Posté le 25-11-2005 à 10:40:24    

the real moins moins a écrit :

(cfr avant-derniere page (je crois) sur le topic de l'élite du java mondial de besançon)


quoi donc ? (je trouve pas)


---------------
get amaroK plugin
Reply

Marsh Posté le 25-11-2005 à 10:40:42    

certes.
mais un machin propre aurait pas pris plus longtemps.
voire encore moins longtemps si commons-discovery était documenté.


---------------
Hey toi, tu veux acheter des minifigurines Lego, non ?
Reply

Marsh Posté le 25-11-2005 à 10:43:33    

je note, je note :D


---------------
get amaroK plugin
Reply

Marsh Posté le 25-11-2005 à 10:53:00    

merde quel crétin, je me suis platé de topic !!!
http://forum.hardware.fr/hardwaref [...] m#t1252443


---------------
trainoo.com, c'est fini
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed