Многие из нас знают о существовании Java HotSpot VM Swap механизме, который позволяет сделать «горячую» замену и избежать перезапуск всего сервера приложений.
В IntelliJ IDEA можно использовать комбинацию клавиш (?: Command+Shift+F9/ ?: Ctrl+Shift+F9)
В силу существующих ограничений Java HotSpot, позволяет это делать только для изменения тела существующих методов класса. В остальных случаях, измененные классы не будут обновлены при «горячей замене».
Для того что бы преодолеть это ограничение, можно воспользоваться Dynamic Code Evolution Virtual Machine (DCEVM) — это модификация Java HotSpot(TM) VM, что позволит делать неограниченное количество «горячих» замен классов в режими реального времени.
Иногда простой замены классов недостаточно, особенно при использовании различных фреймворков, например, Spring. В таких случаях необходимо учитывать «жизненный цикл» того или иного фреймворка. Для решений этой проблемы вместе с DCEVM можно использовать специальный агент HotSwapAgent, который расширяет возможности «горячей замены» и упрощает интеграцию с вашей любимой IDE.
Для интеграции с IntelliJ IDEA:
1. Установите специальный HotSwapAgent плагин.
2. Установите «Reload classes after compilation: Always» конфигурацию в IntelliJ IDEA в секции HotSwap.
3. Плагин позволяет активировать HotSwapAgent агент для всего проекта или для определенной конфигурации.
4. В случае успешной конфигурации при запуске в консоли будет отображаться сообщение «HOTSWAP AGENT».
5. Для «горячей замены» необходимо скомпилировать измененные классы, для этого используйте комбинацию клавиш (?: Command+Shift+F9/ ?: Ctrl+Shift+F9).
Несколько примеров для наглядного представления:
Сценарий 1: Изменение тела метода класса.
Сценарий 2: Добавление метода внутрь класса, изменение контроллера.
Приятной "горячей" разработки!
Ссылки:
HotSwap plugin for IntelliJ IDEA, HotSwapAgent project, DCEVM
Комментарии (15)
tbl
05.04.2017 12:55Методы, заинлайненные jit'ом, (всякие простые геттеры/сеттеры, например) тоже заменяются?
WFrag
06.04.2017 04:38Это даже и при обычной перегрузке работает.
Фишка DCEVM в возможности делать произвольные изменения классов (*).
[*] На самом деле, есть несколько ограничений. Можно добавлять интерфейсы к классу, но нельзя менять базовый класс и удалять интерфейсы. Можно добавлять/удалять поля класса, но статические поля не будут должным образом проинициализированны. Сборщик мусора поддерживается только один (хотя для отладки это не столь важно). Есть некоторые проблемы со стабильностью.
Сама большая проблема DCEVM — проект никуда особо не движется и какие у него перспективы (особенно с учётом выхода Java 9) — непонятно.
danilychen
05.04.2017 12:57Попробовал на своем текущем проекте и столкнулся с проблемами. Перестали работать транзакции (проект на Spring + Hibernate). Погуглив наткнулся на баг. Судя по комментариям проблема в Hibernate плагине.
hibissscus
05.04.2017 12:58Спасибо за Ваш комментарий, да для некоторых фреймворков есть текущие баги, можно попробовать отключить плагин для Hibernate, как это описано в тикете, но для этого придется запускать данный агент вторым способом, как это описано здесь. На данный момент плагин для IntelliJ IDEA не поддерживает возможность через конфигурацию включать или отключать отдельные плагины. Мы обязательно добавим эту возможность в одной из следующих версий.
CyberSoft
05.04.2017 13:00Давно использую Ctrl+F9 в идее, и вроде как хватает перезагрузки тела методов для мелких изменений. А вот про DCEVM не слышал, спасибо за наводку!
Gugic
05.04.2017 13:49Давно хотел задаться вопросом поиска более "Hot" Swap, но Java не мой основной профиль и как-то все недосуг. Прочитал вашу статью, настроил и прям работает, удобно. Спасибо.
sshikov
Хорошая вещь. Только «в консоле» слегка режет глаз )))
Я правильно понимаю, что на уровне VM только и исключительно замена байткода и ресурсов, и ничего более? Т.е. все что дальше (скажем, перезагрузка контекстов Spring) — это делают агент(ы)? Специальные для каждого фреймворка. И по-моему, тут иначе и никак?
hibissscus
Верно! DCEVM обеспечивает «горячую замену» байткода, а агент в свою очередь заботится о различных фреймворках, список поддерживаемых на данный момент можно посмотреть здесь.
webkumo
Близко к этому… Хотсвап-агент поставляется с набором библиотек-агентов, которые при старте ищут свои фреймворки и нициализируются в среде… но если изменения кода проглатываются на ура, то с аннотациями в перезагружаемых классах не всётак радужно… Ни спринг, ни jackson на них у меня не реагируют (возможно старая версия хотсвапа — годовой давности).
sshikov
Я бы этого и не ожидал, если честно. Ну прикиньте, есть у вас запущенное Spring-приложение, которое уже в какой-то момент просмотрело классы в поисках аннотаций, и что-то с ними сделало. Это был один этап жизненного цикла приложения, и он уже выполнен. И тут мы хотим часть приложения подменить.
Как предлагается вернуться к этапу, который уже завершен? По-хорошему, тут нужно только рестартовать приложение (Spring контекст), и ничего больше.
Т.е. в такой ситуации ожидать совсем уж полноценной работы HostSwap не стоит.
webkumo
То, как он работает в других местах заставляет надеяться...