Элегантный способ сравнить содержимое файлов JAR (чтобы найти новые классы и методы) - PullRequest
5 голосов
/ 04 мая 2011

Да, Интернет говорит: «Разархивируйте их все, декомпилируйте и сравните код с помощью какого-либо инструмента (total comander, WinCompare, meld (linux) и т. Д.). Причина, по которой мне нужен инструмент для автоматического создания отчета о различиях из Fodler1 и Folder2 очень просто - в этих папках слишком много JAR-файлов, и мне нужно сравнивать эти папки (со следующей версией Jars), скажем, 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 есть Reflection (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)?

Ответы [ 2 ]

1 голос
/ 19 апреля 2012

Попробуйте утилиту jarcomp .

1 голос
/ 04 мая 2011

Это не является прямым ответом на ваш вопрос, однако вы можете взглянуть на ASM framework. Это позволяет анализировать байт-код без загрузки классов с помощью загрузчика классов. Наверное, так проще сделать.

...