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

Есть ли способ получить классы, загруженные ClassLoader?

Я пытаюсь реализовать некоторое модульное тестирование для старой структуры. Я пытаюсь высмеять слой базы данных. К сожалению, наши рамки немного устарели и не совсем используют передовые методы, поэтому нет четкого разделения проблем. Я немного обеспокоен тем, что попытка обмануть слой базы данных может заставить JVM загружать огромное количество классов, которые даже не будут использоваться.

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

4b9b3361

Ответ 1

Будьте осторожны, используя

java -verbose

Производит огромное количество продукции. Запишите вывод в файл, а затем используйте grep. Если у вас есть фильтр "tee", вы можете попробовать следующее:

java -verbose | tee classloader.log
grep class classloader.log

Ответ 2

Вы можете создать свой собственный загрузчик классов и использовать его для загрузки во время unit test. Попросите свой собственный Classloader распечатать, что он делает.

Или, если вы просто хотите узнать, какие классы загружены, выполните:

java -verbose:class

Ответ 3

Я не уверен. Но есть один из способов понять, что это можно сделать. Это, возможно, чересчур смешно. Вы можете попробовать аспекты и поставить pointcut для loadclass. Также может быть полезным аргумент jvm -verbose.

Ответ 4

Как альтернативный способ для определенного класса-загрузчика, как вы упомянули, вы можете использовать этот фрагмент кода. Просто измените значение переменной obj, если хотите.

Object obj = this;
ClassLoader classLoader = obj.getClass().getClassLoader();
File file = new File("classloderClasses.txt");
if (file.exists()) {
    file.delete();
}
if (classLoader != null) {
    try {
        Class clClass = classLoader.getClass();
        while (clClass != ClassLoader.class) {
            clClass = clClass.getSuperclass();
        }
        java.lang.reflect.Field classesField = clClass.getDeclaredField("classes");
        classesField.setAccessible(true);
        Vector classes = (Vector) classesField.get(classLoader);
        FileOutputStream fos = new FileOutputStream("classloderClasses.txt", true);
        fos.write(("******************** " + classLoader.toString() + " ******************** " + "\n").getBytes());
        fos.write(Arrays.toString(classes.toArray()).getBytes());
        fos.close();
    } catch (Exception exception) {
        exception.printStackTrace();
        // TODO
    }
}