Когда мы программируем, отлаживаем код, ищем пресловутый «баг», зачастую возникает ситуация, когда приходится перезапускать сервер приложений, чтобы увидеть наши изменения. Это приводит к тому, что нам приходится выходить из «потока», разрушать наш хрупкий песочный замок нейронных связей. Отвлекаться от текущей задачи и ждать-ждать-ждать, когда на сервере приложений будут доступны наши изменения. Порой это так утомительно… Как было бы здорово, сделать «горячую» замену измененных классов и сразу увидеть результат.

image

Многие из нас знают о существовании Java HotSpot VM Swap механизме, который позволяет сделать «горячую» замену и избежать перезапуск всего сервера приложений.

image

В IntelliJ IDEA можно использовать комбинацию клавиш (?: Command+Shift+F9/ ?: Ctrl+Shift+F9)

В силу существующих ограничений Java HotSpot, позволяет это делать только для изменения тела существующих методов класса. В остальных случаях, измененные классы не будут обновлены при «горячей замене».

image

Для того что бы преодолеть это ограничение, можно воспользоваться Dynamic Code Evolution Virtual Machine (DCEVM) — это модификация Java HotSpot(TM) VM, что позволит делать неограниченное количество «горячих» замен классов в режими реального времени.

Иногда простой замены классов недостаточно, особенно при использовании различных фреймворков, например, Spring. В таких случаях необходимо учитывать «жизненный цикл» того или иного фреймворка. Для решений этой проблемы вместе с DCEVM можно использовать специальный агент HotSwapAgent, который расширяет возможности «горячей замены» и упрощает интеграцию с вашей любимой IDE.

Для интеграции с IntelliJ IDEA:

1. Установите специальный HotSwapAgent плагин.

image

2. Установите «Reload classes after compilation: Always» конфигурацию в IntelliJ IDEA в секции HotSwap.

image

3. Плагин позволяет активировать HotSwapAgent агент для всего проекта или для определенной конфигурации.

image

4. В случае успешной конфигурации при запуске в консоли будет отображаться сообщение «HOTSWAP AGENT».

image

5. Для «горячей замены» необходимо скомпилировать измененные классы, для этого используйте комбинацию клавиш (?: Command+Shift+F9/ ?: Ctrl+Shift+F9).

Несколько примеров для наглядного представления:

Сценарий 1: Изменение тела метода класса.

image

Сценарий 2: Добавление метода внутрь класса, изменение контроллера.

image

Приятной "горячей" разработки!

Ссылки:
HotSwap plugin for IntelliJ IDEA, HotSwapAgent project, DCEVM
Поделиться с друзьями
-->

Комментарии (15)


  1. sshikov
    05.04.2017 12:15

    Хорошая вещь. Только «в консоле» слегка режет глаз )))

    Я правильно понимаю, что на уровне VM только и исключительно замена байткода и ресурсов, и ничего более? Т.е. все что дальше (скажем, перезагрузка контекстов Spring) — это делают агент(ы)? Специальные для каждого фреймворка. И по-моему, тут иначе и никак?


    1. hibissscus
      05.04.2017 12:24

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


    1. webkumo
      06.04.2017 10:41

      Близко к этому… Хотсвап-агент поставляется с набором библиотек-агентов, которые при старте ищут свои фреймворки и нициализируются в среде… но если изменения кода проглатываются на ура, то с аннотациями в перезагружаемых классах не всётак радужно… Ни спринг, ни jackson на них у меня не реагируют (возможно старая версия хотсвапа — годовой давности).


      1. sshikov
        06.04.2017 10:52

        Я бы этого и не ожидал, если честно. Ну прикиньте, есть у вас запущенное Spring-приложение, которое уже в какой-то момент просмотрело классы в поисках аннотаций, и что-то с ними сделало. Это был один этап жизненного цикла приложения, и он уже выполнен. И тут мы хотим часть приложения подменить.


        Как предлагается вернуться к этапу, который уже завершен? По-хорошему, тут нужно только рестартовать приложение (Spring контекст), и ничего больше.


        Т.е. в такой ситуации ожидать совсем уж полноценной работы HostSwap не стоит.


        1. webkumo
          06.04.2017 16:25

          То, как он работает в других местах заставляет надеяться...


  1. tbl
    05.04.2017 12:55

    Методы, заинлайненные jit'ом, (всякие простые геттеры/сеттеры, например) тоже заменяются?


    1. WFrag
      06.04.2017 04:38

      Это даже и при обычной перегрузке работает.

      Фишка DCEVM в возможности делать произвольные изменения классов (*).

      [*] На самом деле, есть несколько ограничений. Можно добавлять интерфейсы к классу, но нельзя менять базовый класс и удалять интерфейсы. Можно добавлять/удалять поля класса, но статические поля не будут должным образом проинициализированны. Сборщик мусора поддерживается только один (хотя для отладки это не столь важно). Есть некоторые проблемы со стабильностью.

      Сама большая проблема DCEVM — проект никуда особо не движется и какие у него перспективы (особенно с учётом выхода Java 9) — непонятно.


  1. hibissscus
    05.04.2017 12:57

    Да. DCEVM поддерживает возможность модернизировать тело класса.


  1. danilychen
    05.04.2017 12:57

    Попробовал на своем текущем проекте и столкнулся с проблемами. Перестали работать транзакции (проект на Spring + Hibernate). Погуглив наткнулся на баг. Судя по комментариям проблема в Hibernate плагине.


    1. hibissscus
      05.04.2017 12:58

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


      1. hibissscus
        05.04.2017 13:05

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


  1. CyberSoft
    05.04.2017 13:00

    Давно использую Ctrl+F9 в идее, и вроде как хватает перезагрузки тела методов для мелких изменений. А вот про DCEVM не слышал, спасибо за наводку!


  1. Gugic
    05.04.2017 13:49

    Давно хотел задаться вопросом поиска более "Hot" Swap, но Java не мой основной профиль и как-то все недосуг. Прочитал вашу статью, настроил и прям работает, удобно. Спасибо.


    1. hibissscus
      05.04.2017 14:40

      Спасибо, приятно это слышать!


  1. zesetup
    07.04.2017 00:14

    Eще есть spring-loaded.