Как загрузить классы во время выполнения из папки или JAR?



Я пытаюсь сделать инструмент Java, который будет сканировать структуру приложения Java и предоставлять некоторую значимую информацию. Для этого мне нужно иметь возможность сканировать все .файлы классов из расположения проекта (JAR/WAR или просто папка) и использовать отражение, чтобы прочитать об их методах. Это оказывается почти невозможным.



Я могу найти много решений на основе URLClassloader, которые позволяют мне загружать определенные классы из каталога / архива, но ни один из них не будет позвольте мне загружать классы, не имея никакой информации об имени класса или структуре пакета.



изменить:
Я думаю, что я сформулировал это плохо. Моя проблема не в том, что я не могу получить все файлы класса, я могу сделать это с рекурсией и т. д. и найти их правильно. Моя проблема заключается в получении объекта класса для каждого файла класса.

740   3  

3 ответов:

следующий код загружает все классы из файла JAR. Не нужно ничего знать о классах. Имена классов извлекаются из JarEntry.

JarFile jarFile = new JarFile(pathToJar);
Enumeration<JarEntry> e = jarFile.entries();

URL[] urls = { new URL("jar:file:" + pathToJar+"!/") };
URLClassLoader cl = URLClassLoader.newInstance(urls);

while (e.hasMoreElements()) {
    JarEntry je = e.nextElement();
    if(je.isDirectory() || !je.getName().endsWith(".class")){
        continue;
    }
    // -6 because of .class
    String className = je.getName().substring(0,je.getName().length()-6);
    className = className.replace('/', '.');
    Class c = cl.loadClass(className);

}

edit:

как было предложено в комментариях выше, javassist также будет возможность. Инициализируйте пул классов где-то до того, как цикл while сформирует код выше, и вместо загрузки класса с помощью загрузчика классов вы можете создать CtClass объект:

ClassPool cp = ClassPool.getDefault();
...
CtClass ctClass = cp.get(className);

из ctClass вы можете получить все методы, поля, вложенные классы,.... Взгляните на api javassist: https://jboss-javassist.github.io/javassist/html/index.html

Список всех классов внутри jar-файла.

public static List getClasseNames(String jarName) {
    ArrayList classes = new ArrayList();

    if (debug)
        System.out.println("Jar " + jarName );
    try {
        JarInputStream jarFile = new JarInputStream(new FileInputStream(
                jarName));
        JarEntry jarEntry;

        while (true) {
            jarEntry = jarFile.getNextJarEntry();
            if (jarEntry == null) {
                break;
            }
            if (jarEntry.getName().endsWith(".class")) {
                if (debug)
                    System.out.println("Found "
                            + jarEntry.getName().replaceAll("/", "\."));
                classes.add(jarEntry.getName().replaceAll("/", "\."));
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return classes;
}

для этого мне нужно иметь возможность сканировать все .файлы классов из расположения проекта (JAR/WAR или просто папка)

сканирование всех файлов в папке простое. Один из вариантов-позвонить File.listFiles() на File что обозначает папку, а затем повторите полученный массив. Для обхода деревьев вложенных папок используйте рекурсию.

сканирование файлов файла JAR может быть сделано с помощью JarFile API ... и вам не надо обратиться к пересеките вложенные "папки".

ни один из них не является особенно сложным. Просто прочитайте javadoc и начните кодирование.

Comments

    Ничего не найдено.