В прошлом посте я рассказывал, как работает механизм загрузки классов в JVM. Сегодня разберём, как дебажить проблемы, которые возникают из-за загрузчиков. А это, между прочим, один из самых частых источников боли в больших проектах.
🧨 Типичная проблема:
ClassCastException: class com.example.MyClass cannot be cast to class com.example.MyClass
Текст ошибки одинаковый класс... но JVM считает их разными. Почему?
👉 У каждого
Class в JVM есть два признака уникальности:1. Полное имя (
com.example.MyClass)2. Загрузчик (
ClassLoader)Если один и тот же класс загружен разными загрузчиками, JVM считает, что это разные классы. Отсюда и ошибки.
🛠 Как дебажить:
1. Вывести загрузчик:
System.out.println(myObject.getClass().getClassLoader());
2. Сравнить загрузчики:
Убедись, что два экземпляра класса загружены одним и тем же
ClassLoader.3. JVM-флаги:
Добавь при запуске:
-verbose:class
Это покажет, откуда и каким загрузчиком загружался каждый класс.
4. Используй инструменты:
-
jvisualvm (вкладка "Class Loader")-
jconsole- плагин для IntelliJ: "Classloader Leak Prevention"
📌 А что такое child-first загрузчики?
По умолчанию Java использует parent-first стратегию: сначала спрашивает родителя, и только потом загружает сама. Но иногда нужно наоборот — особенно в системах с плагинами, чтобы изолировать версии зависимостей.
👉@BookJava