web-dev-qa-db-fra.com

Obter todas en tant que classes no caminho de classe

Si vous avez déjà une liste des tâches disponibles, les classes disponibles CLASSPATH au-dessus du délai d'exécution?
Non Eclipse IDE, il est recommandé de modifierCtrl+Shift+T.
Existe algum método em en Java pour lire?

40
arash

Vous pouvez obtenir toutes les racines de classpath en passant une String vide dans ClassLoader#getResources() .

Enumeration<URL> roots = classLoader.getResources("");

Vous pouvez construire une File basée sur URL comme suit:

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

Vous pouvez utiliser File#listFiles() pour obtenir une liste de tous les fichiers du répertoire donné:

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

Vous pouvez utiliser les méthodes Java.io.File standard pour vérifier s’il s’agit d’un répertoire et/ou pour récupérer le nom du fichier.

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.
}

En fonction de la seule exigence fonctionnelle, je suppose que la bibliothèque de réflexions est bien plus exactement ce que vous voulez. 

52
BalusC

Voici ce que j'ai écrit pour le faire. Je suis sûr que tout ne fonctionne pas si vous faites quelque chose de bizarre avec le classpath, mais cela semble bien fonctionner pour moi. Notez qu'il ne charge pas les classes, il renvoie simplement leurs noms. Ceci afin de ne pas charger toutes les classes en mémoire, et parce que certaines classes de la base de code de mon entreprise provoquaient des erreurs d'initialisation si elles étaient chargées au mauvais moment ...

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();
    }
}

Pour l'utiliser:

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
    }
});
17
Andy

Vous pouvez utiliser les classes d’utilitaires du paquetage com.google.common.reflect de la bibliothèque Guava. Par exemple. pour obtenir toutes les classes dans un package particulier:

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

Ceci est concis, mais les mises en garde décrites dans les autres réponses s'appliquent toujours, à savoir qu’il ne trouvera généralement que les classes chargées par un ClassLoader «standard», par exemple URLClassLoader.

7
Matthew Wise

De temps en temps, je cherche ceci. C'est un peu difficile car même si vous parvenez à tout trouver dans le chemin de classe, vous ne trouverez peut-être pas tout ce qui est disponible pour un chargeur de classes donné (par exemple, j'ai travaillé sur un projet qui chargeait une fois les définitions de classe directement à partir d'une base de données).

Le meilleur pari à ce stade est probablement de regarder au printemps. Ils analysent les classes sur le classpath pour voir si certaines annotations ont besoin d’être relancées.

La réponse acceptée ici est un bon point de départ:

Analyse des annotations Java à l'exécution

0
Bill K

Je suggère d'utiliser PathMatchingResourcePatternResolver de Spring;

Cela fera l'affaire aussi bien pour lancer le paquet depuis un IDE que depuis le système de fichiers:

Pour plus de détails, consultez ma note ici:

Comment obtenir des ressources d'un paquet

0
Naor Bar