Я реализую функцию, которая требует передачи динамически сгенерированных типов (в двоичном представлении, сериализованном с помощью Kryo) между несколькими экземплярами JVM (по сети). Чтобы правильно решить, какие типы загружены, а что нет, я использую пользовательский загрузчик системного класса (переданный как параметр java -Djava.system.class.loader
), который используется другими динамически создаваемыми загрузчиками классов в качестве родителя. Этот пользовательский загрузчик системных классов знает о своих дочерних элементах, и в случае, если он не может найти класс, эти загрузчики производных классов могут быть заданы, если они есть (это обратное к стандартной иерархической структуре загрузчиков классов).Пользовательский системный загрузчик классов не используется всеми классами
Эти динамически генерируемые типы передаются и загружаются между различными JVM отлично. Проблема возникает, когда я пытаюсь десериализировать экземпляр некоторого типа (соответствующий класс загружается с диска и идентичен для всех JMV), который ссылается на один из динамически сгенерированных типов - ClassNotFoundException воссоздается экземпляром Kryo, который пытается readClass
по имени динамически сгенерированного типа.
Внутри метода readClass
есть вызов Class.forName
, который, в свою очередь, не использует указанный пользовательский загрузчик классов (который знает всех динамически создаваемых типов), а вместо этого использует экземпляр sun.misc.Launcher $ AppClassLoader.
Можно ли указать пользовательский системный загрузчик классов, чтобы все классы загружались вместе с ним, чтобы избежать описанной проблемы?
Update
Дальнейший анализ показал, что ClassLoader.getSystemClassLoader()
фактически возвращает указанный пользовательский класс системный загрузчик. К счастью, библиотека Kryo поддерживает настройку пользовательского загрузчика классов специально для загрузки классов при десериализации. Эти два факта легли в основу решения описанной проблемы.
Конечно ... Я просто надеялся, что JVM проанализирует минимально необходимые классы для загрузки, чтобы загрузить сам java.system.class.loader, а затем загрузить все остальное с ним. Thanx для ваших предложений. – 01es
Я считаю, что предполагается, что вы не измените минимальный набор классов, чтобы их не нужно было перезагружать. –
Их не нужно перезагружать, но их экземпляры могут начать ссылаться на экземпляры полиморфно совместимых типов, загружаемых динамически, и в результате их не смогут найти их с использованием класса по умолчанию, загруженного во время процесса сериализации/десериализации. Существует ли окончательный справочный материал по теме загрузки классов, встроенных агентов инструментария и пользовательских реализаций AppClassLoader? Спецификация JVM? Спасибо. – 01es