Obtén todas las clases en Classpath

¿Cómo puedo obtener una lista de todas las clases disponibles en CLASSPATH en tiempo de ejecución?
En Eclipse IDE, puede hacer esto presionando Ctrl + Shift + T.
¿Hay algún método en Java para hacerlo?

Puede obtener todas las raíces de classpath pasando una String vacía en ClassLoader#getResources() .

 Enumeration roots = classLoader.getResources(""); 

Puede construir un File basado en la URL siguiente manera:

 File root = new File(url.getPath()); 

Puede usar File#listFiles() para obtener una lista de todos los archivos en el directorio indicado:

 for (File file : root.listFiles()) { // ... } 

Puede usar los métodos estándar java.io.File para verificar si es un directorio y / o para tomar el nombre del archivo.

 if (file.isDirectory()) { // Loop through its listFiles() recursively. } else { String name = file.getName(); // Check if it's a .class file or a .jar file and handle accordingly. } 

Según el único requisito funcional, supongo que la biblioteca Reflections es mucho más exactamente lo que quieres.

Esto es lo que escribí para hacerlo. Estoy seguro de que no consigue todo si estás haciendo algo extraño con el classpath, pero parece funcionar bien para mí. Tenga en cuenta que en realidad no carga las clases, simplemente devuelve sus nombres. Esto es para que no cargue todas las clases en la memoria, y porque algunas clases en la base de código de mi compañía estaban causando errores de inicialización si se cargaban en el momento equivocado …

 public interface Visitor { /** * @return {@code true} if the algorithm should visit more results, * {@code false} if it should terminate now. */ public boolean visit(T t); } public class ClassFinder { public static void findClasses(Visitor visitor) { String classpath = System.getProperty("java.class.path"); String[] paths = classpath.split(System.getProperty("path.separator")); String javaHome = System.getProperty("java.home"); File file = new File(javaHome + File.separator + "lib"); if (file.exists()) { findClasses(file, file, true, visitor); } for (String path : paths) { file = new File(path); if (file.exists()) { findClasses(file, file, false, visitor); } } } private static boolean findClasses(File root, File file, boolean includeJars, Visitor visitor) { if (file.isDirectory()) { for (File child : file.listFiles()) { if (!findClasses(root, child, includeJars, visitor)) { return false; } } } else { if (file.getName().toLowerCase().endsWith(".jar") && includeJars) { JarFile jar = null; try { jar = new JarFile(file); } catch (Exception ex) { } if (jar != null) { Enumeration entries = jar.entries(); while (entries.hasMoreElements()) { JarEntry entry = entries.nextElement(); String name = entry.getName(); int extIndex = name.lastIndexOf(".class"); if (extIndex > 0) { if (!visitor.visit(name.substring(0, extIndex).replace("/", "."))) { return false; } } } } } else if (file.getName().toLowerCase().endsWith(".class")) { if (!visitor.visit(createClassName(root, file))) { return false; } } } return true; } private static String createClassName(File root, File file) { StringBuffer sb = new StringBuffer(); String fileName = file.getName(); sb.append(fileName.substring(0, fileName.lastIndexOf(".class"))); file = file.getParentFile(); while (file != null && !file.equals(root)) { sb.insert(0, '.').insert(0, file.getName()); file = file.getParentFile(); } return sb.toString(); } } 

Para usarlo:

 ClassFinder.findClasses(new Visitor() { @Override public boolean visit(String clazz) { System.out.println(clazz) return true; // return false if you don't want to see any more classes } }); 

Puede utilizar las clases de utilidad del paquete com.google.common.reflect de la biblioteca de Guava. Por ejemplo, para obtener todas las clases en un paquete particular:

  ClassLoader cl = getClass().getClassLoader(); Set classesInPackage = ClassPath.from(cl).getTopLevelClassesRecursive("com.mycompany.mypackage"); 

Esto es conciso, sin embargo, las mismas advertencias que otras respuestas describen, todavía se aplican, es decir, que generalmente solo encontrará las clases cargadas por un ClassLoader ‘estándar’, por ejemplo, URLClassLoader .

De vez en cuando busco esto. Es un poco difícil porque incluso si logras encontrar todo en el classpath, es posible que no encuentres todo disponible para un cargador de clases dado (por ejemplo, trabajé en un proyecto que cargó definiciones de clases directamente desde un DB).

La mejor apuesta en este punto es probablemente mirar hacia Spring. Escanean las clases en el classpath para ver si tienen anotaciones que necesitan para iniciar cosas.

La respuesta aceptada aquí es un buen lugar para comenzar:

Escaneo de anotaciones Java en tiempo de ejecución

Sugiero usar Spring’s PathMatchingResourcePatternResolver ;

Hará el truco para lanzar el paquete desde un IDE o desde el sistema de archivos:

Para más detalles, consulte mi nota aquí:

Cómo obtener recursos de un paquete