Подтвердить что ты не робот

Как найти, какие банки и в каком порядке загружаются загрузчиком классов?

Я не мог найти четкого ответа на этот вопрос в другом месте, поэтому я попробую здесь:

Есть ли какой-то способ (программный или другой), чтобы получить список JAR/классов, загружаемых загрузчиком классов приложений, в том порядке, в котором они были загружены? Посредством Application Classloader я подразумеваю загрузчик классов, который загружает приложение EAR на сервере приложений (WLS, WAS, JBoss...), но, очевидно, это относится к любому загрузчику классов.

Итак, чтобы обобщить, я хотел бы узнать список и порядок JAR, загруженные указанным загрузчиком классов. Не отдельные классы, которые достаточно легко узнать, вызывая classloader.getPackages(), но список файлов JAR, загруженных этим загрузчиком классов.

4b9b3361

Ответ 1

Короткий ответ - нет. Classloaders не обязаны раскрывать свою логику поиска.

Однако, если ваш экземпляр classloader оказывается URLClassLoader или подкласс, тогда у вас есть доступ к списку баннеров/каталогов, используя метод getURLs(). В отношении документа для этого класса эти URL-адреса будут выполняться по порядку.

На практике, если вы пытаетесь выяснить, откуда загружается класс, ответ Стив скорее полезен.

Ответ 2

Вы пытались использовать опцию JVM -verbose:class. Он отображает все загруженные файлы JAR и классы.

Пример:

[Opened C:\Program Files\JDK160~1\jre\lib\rt.jar]
[Loaded java.lang.Object from C:\Program Files\JDK160~1\jre\lib\rt.jar]

Ответ 3

Пройдите через Защитный домен класса (комбинация местоположения/сертификата). например для PDFParser.class вы получите это как...

PDFParser.class.getProtectionDomain().getCodeSource().getLocation().toString()

Если он загружен из классов jre или из одобренных dirs, он выдает исключение, потому что эти классы загружаются без защиты...

Ответ 4

Как альтернативный способ, вы можете использовать этот фрагмент кода. Результатом является файл, который состоит из связанных файлов jar с файлами класса-загрузчика и класса, которые загружаются классом-загрузчиками объектов (цепочка классов-загрузчиков, включая его родителей, до корневого загрузчика классов). Класс-погрузчики разделены звездами.

Object obj = this;
ClassLoader classLoader = obj.getClass().getClassLoader();
File file = new File("classlodersClassesJars.txt");
if(file.exists()) {
    file.delete();
}
if(classLoader != null) { // to escape from system classes that are loaded by bootstrap class-loader such as String.
    do {
        try {
            Class clClass = classLoader.getClass();
            while(clClass != ClassLoader.class){
                    clClass = clClass.getSuperclass();
            }
            java.lang.reflect.Field domainField = clClass.getDeclaredField("domains");
            java.lang.reflect.Field classesField = clClass.getDeclaredField("classes");
            domainField.setAccessible(true);
            classesField.setAccessible(true);
            HashSet domains = (HashSet<String>) domainField.get(classLoader);
            Vector classes = (Vector) classesField.get(classLoader);
            FileOutputStream fos = new FileOutputStream("classlodersClassesJars.txt", true);
            fos.write(("\n******************** " + classLoader.toString() + "\n").getBytes());
            fos.write(Arrays.toString(classes.toArray()).getBytes());
            Object[] reverseDomains = domains.toArray();
            org.apache.commons.lang.ArrayUtils.reverse(reverseDomains);
            fos.write(Arrays.toString(reverseDomains).getBytes());
            fos.close();
            classLoader = classLoader.getParent();
        } catch (Exception exception) {
            exception.printStackTrace();
            // TODO
        }
    } while (classLoader.getParent() != null);
}