Comment obtenir toutes les classes d'un package?Java Package Introspection
Répondre
Vous ne pouvez pas. Les classes peuvent entrer par l'intermédiaire de plusieurs chargeurs de classe différents, y compris ceux à distance.
Il n'existe pas de méthode globale pour cela. Cela dit, si vous savez d'où proviennent vos classes, vous pouvez parcourir le répertoire d'un fichier jar ou le système de fichiers.
Il y a un extrait de here qui fait exactement ce que vous voulez, en supposant les classes peut être trouvée localement :
private static Class[] getClasses(String packageName)
throws ClassNotFoundException, IOException {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
assert classLoader != null;
String path = packageName.replace('.', '/');
Enumeration<URL> resources = classLoader.getResources(path);
List<File> dirs = new ArrayList<File>();
while (resources.hasMoreElements()) {
URL resource = resources.nextElement();
dirs.add(new File(resource.getFile()));
}
ArrayList<Class> classes = new ArrayList<Class>();
for (File directory : dirs) {
classes.addAll(findClasses(directory, packageName));
}
return classes.toArray(new Class[classes.size()]);
}
private static List<Class> findClasses(File directory, String packageName) throws ClassNotFoundException {
List<Class> classes = new ArrayList<Class>();
if (!directory.exists()) {
return classes;
}
File[] files = directory.listFiles();
for (File file : files) {
if (file.isDirectory()) {
assert !file.getName().contains(".");
classes.addAll(findClasses(file, packageName + "." + file.getName()));
} else if (file.getName().endsWith(".class")) {
classes.add(Class.forName(packageName + '.' + file.getName().substring(0, file.getName().length() - 6)));
}
}
return classes;
}
Est-ce que cela fonctionne avec les classes jar'ed? –
Autant que je peux dire que cela échouera si vous avez un jar (-1), mais est une routine décente pour rechercher des fichiers .class pour la découverte (+1) afin que vous atteignez l'équilibre :) –
Le code ci-dessus suppose non seulement que les classes du package donné sont locales, mais aussi qu'elles ont toutes été chargées par le même chargeur de classe ET qu'elles n'ont pas été empaquetées. – ChssPly76
Java n'a pas découverte. La plupart des produits qui ont la capacité d'ajouter (découvrir) de nouvelles classes ont un fichier texte décrivant "Program Extensions" ou un répertoire spécifique où vous pouvez placer des classes ou des jars qui utilisent un truc comme @JG décrit. (C'est ce que fait eclipse et est recommandé pour toute solution où l'utilisateur peut ajouter le nouveau module à la main)
N'oubliez pas les API SPI pour les plugins. Ceux-ci fournissent une solution raisonnablement élégante pour les frameworks de plugin. – jsight
Voici une façon plus complète de résoudre cela pour les pots, basée sur l'idée publiée par JG.
/**
* Scans all classloaders for the current thread for loaded jars, and then scans
* each jar for the package name in question, listing all classes directly under
* the package name in question. Assumes directory structure in jar file and class
* package naming follow java conventions (i.e. com.example.test.MyTest would be in
* /com/example/test/MyTest.class)
*/
public Collection<Class> getClassesForPackage(String packageName) throws Exception {
String packagePath = packageName.replace(".", "/");
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
Set<URL> jarUrls = new HashSet<URL>();
while (classLoader != null) {
if (classLoader instanceof URLClassLoader)
for (URL url : ((URLClassLoader) classLoader).getURLs())
if (url.getFile().endsWith(".jar") // may want better way to detect jar files
jarUrls.add(url);
classLoader = classLoader.getParent();
}
Set<Class> classes = new HashSet<Class>();
for (URL url : jarUrls) {
JarInputStream stream = new JarInputStream(url.openStream()); // may want better way to open url connections
JarEntry entry = stream.getNextJarEntry();
while (entry != null) {
String name = entry.getName();
int i = name.lastIndexOf("/");
if (i > 0 && name.endsWith(".class") && name.substring(0, i).equals(packagePath))
classes.add(Class.forName(name.substring(0, name.length() - 6).replace("/", ".")));
entry = stream.getNextJarEntry();
}
stream.close();
}
return classes;
}
-1 pas de documentation ou même un indice sur ce qu'il fait, +2 car il semble qu'il scanne le classpath et inclut des bocaux! donc vous net un +1 :) –
(Eh bien, il y avait un indice sur ce qu'il fait .. Je le reprends). –
Ajout d'un en-tête javadoc pour une meilleure explication. :) – toluju
- 1. package java dans jsp
- 2. Introspection .NET VS Réflexion
- 3. JavaBean Introspection dans Servlets [Tomcat]
- 4. package d'erreur de servlet java doesnot existe
- 5. Assistance requise avec Java Colt Matrix Package
- 6. Actionscript 3 introspection - noms de fonctions
- 7. Python introspection: Comment obtenir une liste 'non triée' d'attributs d'objets?
- 8. Python introspection ne pas afficher les fonctions pour verrouiller
- 9. DateTime package
- 10. package réseau dans GHC
- 11. Package Eclipse personnalisé
- 12. Obfuscating Setup package content
- 13. Lucene Javadoc package
- 14. Déploiement d'un package SSIS
- 15. Package d'analyse SharePoint 2007
- 16. Package de mappage Hibernate
- 17. package SSIS OnError Connexion
- 18. PackageHtml-rule de Checkstyle ignore package-info.java
- 19. Les beans de package n'existent pas
- 20. Comment créer un package pour différents fichiers?
- 21. Comment utiliser le package wx.lib.docview?
- 22. Package de distribution des calculs
- 23. Projets de Eclipse Package Explorer
- 24. Autorisations sur le package SSIS
- 25. wxpython ogl package drag événement
- 26. Delphi: Package requis non trouvé
- 27. Package ERP Extensible Open Source
- 28. Impossible d'exécuter mon package SSIS
- 29. Définir l'association de fichier par défaut Mac OS X Programme d'installation Java Package Maker
- 30. Comment faites-vous référence à une classe Java dans le même package à partir d'un Clojure?
Notez également [cet article] (http://stackoverflow.com/q/520328/1005481). –