*Mise à JOUR*
OK, j'ai enfin eu le temps de faire le ménage dans l'extrait de code ci-dessous. Je l'ai coincé dans son propre projet github et même l'ajout de tests.
https://github.com/ddopson/java-class-enumerator
*Post Original*
Strictement parlant, il n'est pas possible de dresser la liste des classes dans un package. C'est parce qu'un package est vraiment rien de plus qu'un espace de noms (par exemple com.epicapplications.foo.bar), et tout le jar fichier dans le chemin de classe pourrait éventuellement ajouter des classes dans un package. Pire encore, le chargeur de classe classes de charge sur demande, et une partie du classpath peut-être de l'autre côté d'une connexion réseau.
Il est possible de résoudre un plus restrictive problème. par exemple, toutes les classes dans un fichier JAR, ou toutes les classes d'un fichier JAR, définit à l'intérieur d'un paquet particulier. C'est le plus souvent de toute façon.
Malheureusement, il n'existe pas de code de la structure pour rendre cette tâche facile. Vous devez analyser le système de fichiers d'une manière similaire à la façon dont le chargeur de classe serait à la recherche de définitions de classe.
Il y a beaucoup d'exemples sur le web pour les fichiers de classe dans la plaine du-vieux-répertoires. La plupart d'entre nous ces jours-travailler avec les fichiers JAR.
Pour obtenir des choses à travailler avec les fichiers JAR, essayez ceci...
private static ArrayList<Class<?>> getClassesForPackage(Package pkg) {
String pkgname = pkg.getName();
ArrayList<Class<?>> classes = new ArrayList<Class<?>>();
// Get a File object for the package
File directory = null;
String fullPath;
String relPath = pkgname.replace('.', '/');
System.out.println("ClassDiscovery: Package: " + pkgname + " becomes Path:" + relPath);
URL resource = ClassLoader.getSystemClassLoader().getResource(relPath);
System.out.println("ClassDiscovery: Resource = " + resource);
if (resource == null) {
throw new RuntimeException("No resource for " + relPath);
}
fullPath = resource.getFile();
System.out.println("ClassDiscovery: FullPath = " + resource);
try {
directory = new File(resource.toURI());
} catch (URISyntaxException e) {
throw new RuntimeException(pkgname + " (" + resource + ") does not appear to be a valid URL / URI. Strange, since we got it from the system...", e);
} catch (IllegalArgumentException e) {
directory = null;
}
System.out.println("ClassDiscovery: Directory = " + directory);
if (directory != null && directory.exists()) {
// Get the list of the files contained in the package
String[] files = directory.list();
for (int i = 0; i < files.length; i++) {
// we are only interested in .class files
if (files[i].endsWith(".class")) {
// removes the .class extension
String className = pkgname + '.' + files[i].substring(0, files[i].length() - 6);
System.out.println("ClassDiscovery: className = " + className);
try {
classes.add(Class.forName(className));
}
catch (ClassNotFoundException e) {
throw new RuntimeException("ClassNotFoundException loading " + className);
}
}
}
}
else {
try {
String jarPath = fullPath.replaceFirst("[.]jar[!].*", ".jar").replaceFirst("file:", "");
JarFile jarFile = new JarFile(jarPath);
Enumeration<JarEntry> entries = jarFile.entries();
while(entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
String entryName = entry.getName();
if(entryName.startsWith(relPath) && entryName.length() > (relPath.length() + "/".length())) {
System.out.println("ClassDiscovery: JarEntry: " + entryName);
String className = entryName.replace('/', '.').replace('\\', '.').replace(".class", "");
System.out.println("ClassDiscovery: className = " + className);
try {
classes.add(Class.forName(className));
}
catch (ClassNotFoundException e) {
throw new RuntimeException("ClassNotFoundException loading " + className);
}
}
}
} catch (IOException e) {
throw new RuntimeException(pkgname + " (" + directory + ") does not appear to be a valid package", e);
}
}
return classes;
}