#java #jar #classloader
#java #jar #classloader
Вопрос:
Да, в Интернете написано — «распакуйте их все, декомпилируйте и сравните код с помощью какого-нибудь инструмента (total comander, WinCompare, meld (Linux), чего угодно …) Причина, по которой мне нужен инструмент для автоматической генерации отчета о различиях из Fodler1 и Folder2, проста — в этих папках слишком много JAR, и мне нужно сравнивать эти папки (со следующей версией Jar), скажем, 1 раз в месяц. Итак, я действительно совсем не хочу делать это вручную!
Давайте посмотрим, что у меня получилось на данный момент:
1) Я могу найти все JAR в каждой папке 🙂
2) Я могу получить список классов из каждого JAR:
private static void AddAllClassesFromJAR(JarInputStream jarFile,
ArrayList<String> classes) throws IOException {
JarEntry jarEntry = null;
while (true) {
jarEntry = jarFile.getNextJarEntry();
if (jarEntry == null) {
break;
}
if (jarEntry.getName().endsWith(".class")) {
classes.add(jarEntry.getName());
}
}
}
public static List<String> getClasseNamesInPackage(String jarName) {
ArrayList<String> classes = new ArrayList<String>();
try {
JarInputStream jarFile = new JarInputStream(new FileInputStream(jarName));
AddAllClassesFromJAR(jarFile, classes);
} catch (Exception e) {
e.printStackTrace();
}
return classes;
}
3) В Java есть отражение (Core Java 2, том I — Основы, пример 5-5), поэтому я могу получить список методов из одного класса, как только узнаю его название.
Для этого мне нужно создать экземпляр каждого класса, проблема в том, как я могу создать экземпляр каждого класса, который я получил из каждого файла JAR? Теперь я загружаю каждый JAR:
loader_left = new JarClassLoader("left/1.jar");
public class JarClassLoader extends URLClassLoader {
public JarClassLoader( URL url ) {
super( new URL[]{url} );
}
public JarClassLoader( String urlString ) throws MalformedURLException {
this( new URL( "jar:file://" urlString "!/" ) );
}
Никаких исключений, но я не могу найти в нем ни одного ресурса, пытаясь загрузить класс, подобный:
class_left = loader_left.loadClass("level1.level2.class1");
И получаем «java.lang.ClassNotFoundException».
Есть какие-нибудь ссылки, в чем проблема? (имя класса проверено. он жестко запрограммирован только для тестирования, в идеале он должен получать его из списка классов)
Второй вопрос: поскольку большинство классов в Folder1 и Folder2 будут одинаковыми, что произойдет, если я загружу тот же класс во второй раз (из Fodler2)?
Комментарии:
1. Просто интересно из любопытства, зачем вам это нужно делать.
Ответ №1:
Попробуйте утилиту jarcomp.
Ответ №2:
Это не дает прямого ответа на ваш вопрос, однако вы можете ознакомиться с фреймворком ASM . Это позволяет анализировать байт-код без необходимости загружать классы с помощью загрузчика классов. Вероятно, проще сделать это таким образом.
Комментарии:
1. Спасибо, Данило, ты дал мне правильное направление — «анализировать байт-код файлов классов»… Я нашел библиотеку BCEL ( jakarta.apache.org/bcel ).