Как найти, какие банки и в каком порядке загружаются загрузчиком классов? - PullRequest
42 голосов
/ 01 февраля 2010

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

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

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

Ответы [ 4 ]

73 голосов
/ 23 февраля 2010

Вы пытались использовать опцию 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]
14 голосов
/ 23 февраля 2010

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

Однако, если ваш экземпляр загрузчика классов окажется URLClassLoader или подклассом, у вас есть доступ к списку фляг / каталогов черезметод getURLs().Согласно документу для этого класса, эти URL будут искать в следующем порядке.

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

1 голос
/ 28 июня 2017

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

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

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

0 голосов
/ 05 сентября 2017

В качестве альтернативы вы можете использовать этот фрагмент кода. В результате получается файл, который состоит из связанных 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);
}
...