Есть ли способ получить классы, загруженные ClassLoader?
Я пытаюсь реализовать некоторое модульное тестирование для старой структуры. Я пытаюсь высмеять слой базы данных. К сожалению, наши рамки немного устарели и не совсем используют передовые методы, поэтому нет четкого разделения проблем. Я немного обеспокоен тем, что попытка обмануть слой базы данных может заставить JVM загружать огромное количество классов, которые даже не будут использоваться.
Я действительно не понимаю классных загрузчиков, поэтому это может и не быть проблемой. Есть ли способ взять пик во всех классах, которые загрузил определенный ClassLoader, чтобы доказать, что происходит под капотом?
Ответы
Ответ 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
}
}