Обновите код Java во время выполнения

Около года назад я наткнулся на замечательную функцию в Java, которую я не могу найти снова.

Через некоторый волшебный интерфейс было возможно объявить некоторые классы или функции заменяемыми во время выполнения.
Я нашел хороший пример руководства для кого-то, кто запускал простую небольшую программу, которая печатала определенное сообщение, затем он обновил программу, используя метод, который я больше не могу вспомнить, и внезапно программа заменила эту старую функцию печати новой.

Я пытался просмотреть Java API, чтобы зажечь мою память, а также поиск в Google, но безуспешно. Может кто-нибудь здесь помочь?

3 ответа

Решение

Различные контейнеры приложения могут сделать это.

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

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

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

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

Технология HotSwap была добавлена ​​в Java 1.4 и позволяет заменять файлы классов во время выполнения. Функция предоставляется через redefineClassesметод комплектации приборов. Я думаю, что вы также можете сделать это через интерфейс JPDA.

Вот также ссылка на то, что, я считаю, является исследовательской работой, в которой сначала описывается механизм HotSwap:

В противном случае вы можете использовать Classloader, как уже упоминалось, но он обеспечивает только динамическую загрузку классов, а не замену. Один и тот же класс, загруженный дважды, будет рассматриваться как два разных типа. В сочетании с интерфейсом и / или небольшим количеством размышлений, он, однако, может предоставить способы обновления приложения во время выполнения.

Вот ссылка на удивительный документ о загрузчике классов и его использовании:

Я не буду подробно останавливаться на том, хорошо это или плохо, потому что это был не ваш вопрос, но я думаю, что здорово иметь поддержку для эволюции программного обеспечения во время выполнения - слишком плохо, что JSR-117 никогда не делал этого!

Как правило, это тот тип функциональности, который я с удовольствием оставляю инфраструктуре, так как трудно понять, что правильно, и легко ошибиться. Как уже упоминал Джон, большинству приложений это не нужно, а для тех, кому это нужно, доступна инфраструктура.

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

Если это в основном для разработки, вы должны смотреть JRebel, который предоставляет эту функциональность прозрачно. Я слышал, что они работают над решением во время выполнения, но я не знаю, готово ли оно еще к прайм-тайму.

Если вы действительно заинтересованы в том, чтобы заставить это работать, подумайте об использовании OSGi. У него есть крутая кривая обучения, но как только вы это сделаете, он сделает все правильно и будет работать очень хорошо. Я нашел инструменты pax хорошей отправной точкой, но у цепочки инструментов eclipse также есть хорошая поддержка.

Я экспериментировал с этим, и нашел некоторый успех с Eclipse, со следующими шагами. Я использовал Tomcat с Spring Boot.

  1. Запустите приложение в режиме отладки из меню запуска Eclipse.

  2. внести желаемые изменения кода.

  3. снова запустите то же самое приложение на другом порту.

  4. если я смотрю на приложение, запущенное на шаге 1, оно обновляется новым кодом.

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

Другие вопросы по тегам