анализировать файл JAR программно - PullRequest
10 голосов
/ 16 февраля 2012

Мне нужно подсчитать количество скомпилированных классов, интерфейсов и перечислений в данном jar-файле программно (поэтому мне нужно три отдельных числа).Какой API поможет мне?(Я не могу использовать сторонние библиотеки.)

Я уже попробовал довольно хитрую схему, которая кажется не всегда правильной.А именно, я читаю каждый ZipEntry в byte [], а затем передаю результат в мой пользовательский загрузчик классов, который расширяет стандартный CalssLoader и просто отправляет этот байт [] в ClassLoader.defineClass (который защищен и не может быть вызван из кода приложения напрямую).Полный код на Pastebin .

1 Ответ

13 голосов
/ 16 февраля 2012

JAR-файл - это zip-файл с определенным шаблоном. Вы можете использовать ZipFile и ZipEntry или их дочерние классы JarFile и JarEntry.

Этот код (метод пользовательского загрузчика классов) вернет карту с массивами каждого типа «класса», который вам нужен.

public Map<String, List<Class<?>>> loadAndScanJar(File jarFile)
        throws ClassNotFoundException, ZipException, IOException {

    // Load the jar file into the JVM
    // You can remove this if the jar file already loaded.
    super.addURL(jarFile.toURI().toURL());

    Map<String, List<Class<?>>> classes = new HashMap<String, List<Class<?>>>();

    List<Class<?>> interfaces = new ArrayList<Class<?>>();
    List<Class<?>> clazzes = new ArrayList<Class<?>>();
    List<Class<?>> enums = new ArrayList<Class<?>>();
    List<Class<?>> annotations = new ArrayList<Class<?>>();

    classes.put("interfaces", interfaces);
    classes.put("classes", clazzes);
    classes.put("annotations", annotations);
    classes.put("enums", enums);

    // Count the classes loaded
    int count = 0;

    // Your jar file
    JarFile jar = new JarFile(jarFile);
    // Getting the files into the jar
    Enumeration<? extends JarEntry> enumeration = jar.entries();

    // Iterates into the files in the jar file
    while (enumeration.hasMoreElements()) {
        ZipEntry zipEntry = enumeration.nextElement();

        // Is this a class?
        if (zipEntry.getName().endsWith(".class")) {

            // Relative path of file into the jar.
            String className = zipEntry.getName();

            // Complete class name
            className = className.replace(".class", "").replace("/", ".");
            // Load class definition from JVM
            Class<?> clazz = this.loadClass(className);

            try {
                // Verify the type of the "class"
                if (clazz.isInterface()) {
                    interfaces.add(clazz);
                } else if (clazz.isAnnotation()) {
                    annotations.add(clazz);
                } else if (clazz.isEnum()) {
                    enums.add(clazz);
                } else {
                    clazzes.add(clazz);
                }

                count++;
            } catch (ClassCastException e) {

            }
        }
    }

    System.out.println("Total: " + count);

    return classes;
}
...