Обновите код 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.
Запустите приложение в режиме отладки из меню запуска Eclipse.
внести желаемые изменения кода.
снова запустите то же самое приложение на другом порту.
если я смотрю на приложение, запущенное на шаге 1, оно обновляется новым кодом.
Это помогает мне, когда я хочу пропустить долгую настройку инициализации приложения. Однако это не всегда работает: если это не так, помогает перезапуск Eclipse.