2012-04-20 2 views
3

Я реализую функцию, которая требует передачи динамически сгенерированных типов (в двоичном представлении, сериализованном с помощью Kryo) между несколькими экземплярами JVM (по сети). Чтобы правильно решить, какие типы загружены, а что нет, я использую пользовательский загрузчик системного класса (переданный как параметр java -Djava.system.class.loader), который используется другими динамически создаваемыми загрузчиками классов в качестве родителя. Этот пользовательский загрузчик системных классов знает о своих дочерних элементах, и в случае, если он не может найти класс, эти загрузчики производных классов могут быть заданы, если они есть (это обратное к стандартной иерархической структуре загрузчиков классов).Пользовательский системный загрузчик классов не используется всеми классами

Эти динамически генерируемые типы передаются и загружаются между различными JVM отлично. Проблема возникает, когда я пытаюсь десериализировать экземпляр некоторого типа (соответствующий класс загружается с диска и идентичен для всех JMV), который ссылается на один из динамически сгенерированных типов - ClassNotFoundException воссоздается экземпляром Kryo, который пытается readClass по имени динамически сгенерированного типа.

Внутри метода readClass есть вызов Class.forName, который, в свою очередь, не использует указанный пользовательский загрузчик классов (который знает всех динамически создаваемых типов), а вместо этого использует экземпляр sun.misc.Launcher $ AppClassLoader.

Можно ли указать пользовательский системный загрузчик классов, чтобы все классы загружались вместе с ним, чтобы избежать описанной проблемы?


Update

Дальнейший анализ показал, что ClassLoader.getSystemClassLoader() фактически возвращает указанный пользовательский класс системный загрузчик. К счастью, библиотека Kryo поддерживает настройку пользовательского загрузчика классов специально для загрузки классов при десериализации. Эти два факта легли в основу решения описанной проблемы.

ответ

4

Как загрузить пользовательский загрузчик классов, если все классы должны лаять с помощью этого загрузчика классов?

Один из способов обойти это - создать собственный инструментарий. Это загружается до загрузки любых классов.

Другой способ - собрать вашу собственную версию AppClassLoader и префикс к пути к пути к загрузке или добавить его в каталог libs/endorsed.

+0

Конечно ... Я просто надеялся, что JVM проанализирует минимально необходимые классы для загрузки, чтобы загрузить сам java.system.class.loader, а затем загрузить все остальное с ним. Thanx для ваших предложений. – 01es

+0

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

+0

Их не нужно перезагружать, но их экземпляры могут начать ссылаться на экземпляры полиморфно совместимых типов, загружаемых динамически, и в результате их не смогут найти их с использованием класса по умолчанию, загруженного во время процесса сериализации/десериализации. Существует ли окончательный справочный материал по теме загрузки классов, встроенных агентов инструментария и пользовательских реализаций AppClassLoader? Спецификация JVM? Спасибо. – 01es

Смежные вопросы