Динамическая перезагрузка содержимого jar-файлов

У меня есть один файл jar в пути к классу моего приложения. Во время выполнения я добавляю новые классы в файл jar, а иногда также изменяю поля/методы существующих классов. В настоящее время я использую URLClassLoader для динамической загрузки классов. Новые классы, добавленные динамически, загружаются правильно, и я могу использовать их во время выполнения. Но ему не удается перезагрузить существующие классы, измененные во время выполнения. Я читал много статей, в которых говорится, что нам нужно явно обрабатывать перезагрузку, потому что однажды загруженный класс не будет перезагружен до тех пор, пока все ссылки на класс не будут уничтожены. Также я попробовал пример кода, который я нашел, но ни один из них не работал.

Может ли кто-нибудь предложить мне правильный подход к перезагрузке? Любой пример кода для того же будет высоко оценен.


person Ankur Shanbhag    schedule 31.01.2013    source источник
comment
опубликуйте свой код. Я уже делал нечто подобное в одном из своих проектов. Я смогу помочь вам, только когда увижу код.   -  person sakthisundar    schedule 31.01.2013


Ответы (2)


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

Другой вариант — использовать инструментарий для изменения байтового кода существующего класса. Обычно это связано с ограничениями, и изменение полей — это то, что вы не можете сделать. то есть объекты этого типа должны были бы быть как-то переведены.

Обычно я использую сервисы, которые очень быстро запускаются/перезапускаются. Таким образом, вы легко перезапустите процесс, который нуждается в обновленном коде, в идеале, нажав Run в моей среде IDE. Это также минимизирует время развертывания.

person Peter Lawrey    schedule 31.01.2013
comment
Можете ли вы дать мне пример рабочего кода для перезагрузки классов. Это было бы очень полезно. Я попробовал некоторые из подходов, описанных в статьях, но они не сработали. - person Ankur Shanbhag; 31.01.2013
comment
Можете ли вы подтвердить, что готовы выгрузить ClassLoader и любой из загруженных классов? Нет смысла показывать вам сложный пример, который вы не можете использовать. - person Peter Lawrey; 31.01.2013
comment
Да, я готов его разгрузить. Можете ли вы привести пример примера, который может помочь? - person Ankur Shanbhag; 31.01.2013
comment
Создайте счетчик экземпляров, чтобы убедиться, что нет живого экземпляра. - person The Bitman; 04.03.2016

  1. В принципе, уже загруженный класс нельзя повторно загрузить с помощью того же загрузчика классов.
  2. Для новой загрузки необходимо создать новый загрузчик классов и таким образом загрузить класс.
  3. Использование URLClassLoader имеет одну проблему: файл jar остается открытым.
  4. Если у вас есть несколько классов, загруженных из одного jar-файла разными экземплярами URLClassLoader, и вы изменяете jar-файл во время выполнения, вы обычно получаете эту ошибку: java.util.zip.ZipException: ZipFile invalid LOC header (bad signature). Ошибка может быть разной.
  5. Для того, чтобы вышеперечисленные ошибки не возникали, необходимо использовать метод close на всех URLClassLoader с использованием данного jar-файла. Но это решение, которое фактически приводит к перезапуску всего приложения.

Лучшее решение — изменить URLClassLoader так, чтобы содержимое jar-файла загружалось в кеш RAM. Это больше не влияет на другие URLClassloader, которые считывают данные из того же файла jar. Затем файл jar можно свободно изменять во время работы приложения. Например, вы можете использовать эту модификацию URLClassLoader для этой цели: URLClassLoader в памяти

person Richard Kotal    schedule 09.07.2020