Come posso ottenere l'elenco di tutte le classi disponibili in CLASSPATH
in fase di esecuzione?
In Eclipse IDE, è possibile farlo premendo Ctrl + Maiusc +T.
C'è qualche metodo in Java per farlo?Ottenere tutte le classi nel Classpath
risposta
È possibile ottenere tutte le radici del classpath passando uno String
vuoto in ClassLoader#getResources()
.
Enumeration<URL> roots = classLoader.getResources("");
è possibile costruire un File
sulla base di URL
come segue:
File root = new File(url.getPath());
È possibile utilizzare File#listFiles()
per ottenere un elenco di tutti i file nella directory data:
for (File file : root.listFiles()) {
// ...
}
Puoi utilizzare i metodi standard java.io.File
per verificare se si tratta di una directory e/o per prendere il nome file.
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.
}
In base al solo requisito funzionale, immagino che il Reflections library è molto più esattamente quello che vuoi.
Ogni tanto lo cerco. È un po 'difficile perché anche se riesci a trovare tutto sul classpath, potresti non trovare tutto disponibile per un determinato programma di caricamento classi (ad esempio, ho lavorato su un progetto che ha caricato le definizioni di classe direttamente da un DB una volta).
La migliore scommessa a questo punto è probabilmente quella di guardare in primavera. Esaminano le classi sul classpath per vedere se hanno delle annotazioni di cui hanno bisogno per fare il kickstart.
La risposta accettata: ecco un buon punto di partenza:
Ecco quello che ho scritto per farlo. Sono sicuro che non ottiene tutto se stai facendo qualcosa di strano con il classpath, ma sembra funzionare bene per me. Nota che in realtà non carica le classi, restituisce solo i loro nomi. Questo è così che esso non verrà caricato tutte le classi in memoria, e perché alcune classi in codice di base della mia azienda sono stati causando errori di inizializzazione se caricato al momento sbagliato ...
public interface Visitor<T> {
/**
* @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<String> 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<String> 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<JarEntry> 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();
}
}
Per utilizzarlo:
ClassFinder.findClasses(new Visitor<String>() {
@Override
public boolean visit(String clazz) {
System.out.println(clazz)
return true; // return false if you don't want to see any more classes
}
});
È possibile utilizzare le classi di utilità dal pacchetto com.google.common.reflect
dalla libreria Guava. Per esempio. per ottenere tutte le classi in un particolare pacchetto:
ClassLoader cl = getClass().getClassLoader();
Set<ClassPath.ClassInfo> classesInPackage = ClassPath.from(cl).getTopLevelClassesRecursive("com.mycompany.mypackage");
Questo è concisa tuttavia descrivere, si applicano ancora gli stessi avvertimenti come altre risposte, cioè, che sarà generalmente solo trovare classi caricate da un 'standard' ClassLoader esempio URLClassLoader
.
Suggerisco di utilizzare Spring's PathMatchingResourcePatternResolver;
Si farà il trucco sia per il lancio del pacchetto da un IDE o dal file system:
Per maggiori dettagli leggi la mia nota qui:
- 1. Java: loop su tutte le classi nel classpath
- 2. Ottenere Elenco di tutte le classi native
- 3. Ottenere tutte le Classi estesi in PHP
- 4. Ottenere tutte le classi interne per riflessione
- 5. Perché ant compilare tutte le classi ciascuna?
- 6. Analizza il classpath per le classi con annotazioni personalizzate
- 7. Ottenere tutte le classi ereditarie di una generica classe astratta
- 8. Come ottenere tutte le classi con Javassist usando un pattern
- 9. Come ottenere tutte le classi CSS di un elemento?
- 10. Come aggiungere a classpath tutte le classi dall'insieme di directory in formica?
- 11. Come posso trovare tutte le implementazioni dell'interfaccia in classpath?
- 12. C#: elenca tutte le classi nell'assieme
- 13. Vedere tutte le classi super-in Java
- 14. Elenca tutte le classi SENZA Javadoc
- 15. Come posso trovare tutte le implementazioni dell'interfaccia in classpath nel progetto groovy?
- 16. jquery rimuove tutte le classi dalla classe
- 17. Tutte le classi Python dovrebbero estendere l'oggetto?
- 18. Impossibile localizzare compojure nel classpath
- 19. Ottenere tutte le chiavi nel dizionario contenente valore x
- 20. voleva ottenere tutte le date nel risultato mysql
- 21. scansione java classpath nel plug-in maven
- 22. Elenco di tutte le classi di dominio in Grails
- 23. Come ottenere tutte le femmine?
- 24. Più file Log4j.properties nel classpath
- 25. Elenco di tutte le tabelle nel database
- 26. Eclipse crea TUTTE le classi per ogni salvataggio
- 27. Alter tutte le tabelle nel database
- 28. Trovare tutte le classi che implementano un'interfaccia specifica
- 29. Come ottenere classpath da classloader?
- 30. Come ottenere tutte le partite dalla regex?
Cosa si intende per "radici classpath "? Ho notato che 'classLoader.getResources (" ")' restituisce solo una o due directory sul classpath, quelle che sembrano contenere i file .class che ho scritto io stesso (e non quelli in pacchetti di terze parti). – flow2k
E se volessimo l'elenco completo di classpath, non dovremmo usare 'URL [] urls = ((URLClassLoader) classLoader) .getURLs()'? – flow2k