Как загрузить классы во время выполнения из папки или JAR?
Я пытаюсь сделать инструмент Java, который будет сканировать структуру приложения Java и предоставлять некоторую значимую информацию. Для этого мне нужно иметь возможность сканировать все .файлы классов из расположения проекта (JAR/WAR или просто папка) и использовать отражение, чтобы прочитать об их методах. Это оказывается почти невозможным.
Я могу найти много решений на основе URLClassloader, которые позволяют мне загружать определенные классы из каталога / архива, но ни один из них не будет позвольте мне загружать классы, не имея никакой информации об имени класса или структуре пакета.
изменить:
Я думаю, что я сформулировал это плохо. Моя проблема не в том, что я не могу получить все файлы класса, я могу сделать это с рекурсией и т. д. и найти их правильно. Моя проблема заключается в получении объекта класса для каждого файла класса.
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 может быть сделано с помощью
JarFileAPI ... и вам не надо обратиться к пересеките вложенные "папки".ни один из них не является особенно сложным. Просто прочитайте javadoc и начните кодирование.
Comments