Java: поиск * почему * класс загружен

В настоящее время проблема связана с тем, что у меня есть (частичная) программа, которая пытается загрузить класс, но не работает, потому что не может найти этот класс. Если посмотреть на трассировку стека, я не вижу какой-либо конкретной причины, почему VM пытается загрузить этот конкретный класс в первую очередь. Существуют ли какие-либо инструменты, которые позволят мне понять, почему загружается определенный класс?

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

Ответ 1

Запустите программу с помощью флагов -XX:+TraceClassLoading и -XX:+TraceClassResolution. Это создаст LOT вывода, который выглядит следующим образом:

[Loaded com.kdgregory.example.memory.PermgenExhaustion$MyClassLoader from file:/home/kgregory/Workspace/Website/programming/examples/bin/]
RESOLVE com.kdgregory.example.memory.PermgenExhaustion$MyClassLoader java.net.URLClassLoader
RESOLVE java.net.URLClassLoader java.lang.Class URLClassLoader.java:188

Вам нужно будет отслеживать цепочку сообщений RESOLVE для определенного класса. Или, скорее всего, вы увидите ошибку, когда ваша программа пытается загрузить класс, предшествующий сообщениям разрешения для класса, который его загружает).

Ответ 2

Вы можете попробовать инструмент статического анализа, например JDepend, чтобы узнать, какие классы имеют ссылки на этот класс.

Ответ 3

загрузчики классов

Если в игре есть несколько классов-загрузчиков (например, веб-приложение), вы должны быть осторожны. Скажите, пожалуйста, что приложение.

ресурс

Расскажите нам, где находятся банки (структура файла /dir ) и какой класс загружается. Вы загружаете его динамически с помощью Class.forName? или используя spring или другую структуру IOC? Это основной класс?

Некоторое предыдущее тестирование (чтобы помочь нам)

Возможно, вы можете проверить некоторые вещи, используя Class.getResource() из основного метода. Если вы класс foo.bar.Clazz попробуйте Class.getResource( "/foo/bar/Clazz.class" ), чтобы увидеть, возвращает ли он что-то действительное или нет. Попытайтесь сделать то же самое с классом, который загружает ваш неудачный класс, чтобы увидеть, если он там, где вы ожидаете.