Подтвердить что ты не робот

Измените метод во время выполнения через механизм "горячей замены"

Предположим, что у нас есть тривиальная программа Java, состоящая всего из одного класса:

public class HelloWorld {

   private static void replacable(int i) {
      System.out.println("Today is a nice day with a number " + i);
   }        

   public static void main(String[] args) throws Exception {
      for(int i = 0; i < 100000; ++i) {
      replacable(i);
      Thread.sleep(500);
   }
}

После компиляции и запуска вывод будет следующим:

Сегодня хороший день с номером 0

Сегодня хороший день с номером 1

Сегодня хороший день с номером 2

Сегодня хороший день с номером 3

...

Мой вопрос: существует ли (или есть на горизонте) способ обменять метод replacable во время выполнения? Что-то вроде написания другой версии HelloWorld с новой версией replacable, ее компиляции, а затем старой версии в уже запущенной JVM?

Итак, если я напишу новую версию следующим образом:

private static void replacable(int i) {
   System.out.println("Today is an even nicer day with a number " + i);
}  

есть что-то похожее на замену горячего кода Erlang, где я могу это сделать:

  • запустить оригинальную программу
  • написать измененную версию
  • с помощью командной строки, подключитесь к запущенной JVM и замените существующий метод

так что во время выполнения это произойдет:

Сегодня хороший день с номером 15000

Сегодня хороший день с номером 15001

Сегодня еще приятней день с номером 15002

Сегодня еще более приятный день с номером 15003

...

Предположим, что вышеуказанная программа является автономной, работает в стандартной среде Java SE, в classpath нет ничего другого, так что это почти программа стиля Hello Hello.

Примечание. Я знаю, что такие технологии, как манипуляция с байт-кодом (cglib), aspectJ, jRebel, JMX, существует горячая замена методов в Java EE и т.д., но это не то, что Я думал о. Подумайте об Эрланге.

4b9b3361

Ответ 1

Вы можете использовать виртуальную машину HotSpot с открытым исходным кодом или коммерческий плагин JRebel IDE, чтобы легко достичь своей цели (см. Таблицу сравнения здесь).

Ответ 2

Вы можете сделать это через загрузчики классов. Например, если вы знакомы с контейнерами Servlet, такими как tomcat, которые перезагружают страницы по мере их изменения в процессе разработки. Вот отличное объяснение создания динамического кода в java. Это не только объясняет загрузку, но и компиляцию источника на лету. Вы должны быть в состоянии применять концепции, охватываемые любой стратегией перезагрузки кода, который вы хотите использовать.

Ответ 3

Я использовал эту задачу hotswap ant во многих проектах. Целевое приложение java можно запустить с помощью Ant, Eclipse, командной строки или любого другого средства, если оно запущено в режиме отладки при открытии соответствующего порта. На связанной странице содержатся инструкции о том, как это сделать с помощью Ant.

Любое количество классов может быть горячим, если изменения не являются структурными. Смена тела тела обычно сводится к общему состоянию. Код можно отключить, запустив ant script через оболочку или Eclipse.

На работе я использую script, что код hotswaps автоматически изменяется путем сравнения временных меток в файлах классов. Это похоже на образец на странице проекта, который показывает простой пример, что только hotswaps меняли классы.

Примечание: здесь используется JPDA.

Ответ 4

Немного старый пост, но, надеюсь, кто-то найдет это полезным:

Я нашел относительно новый агент Hotswap, хорошо документированный и многофункциональный (и лучше всего с открытым исходным кодом).

Ответ 5

Вы можете сделать это через интерфейс JPDA (Java Platform Debugger Architecture): http://download.oracle.com/javase/1.4.2/docs/guide/jpda/enhancements.html#hotswap

Он не является автоматическим, как случай Erlang - JVM не контролирует путь класса для изменений в файлах классов, а затем перезагружает и повторно связывает их, если их изменить, по довольно очевидным причинам (Java был разработан для веб-развертывания, который вы не хотите опросить URL-адрес http для изменений).

Ответ 6

Как насчет OSGi? Горячая замена является "встроенной" в спецификацию - я бы подумал, что это будет одно из возможных решений.

Ответ 7

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

Ответ 8

Я написал статью по этой теме. Пожалуйста, обратитесь к этому или этому.