2010-12-29 3 views
52

Предположит, что мы имеем тривиальную программу 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's hot code swapping, где я могу это сделать:

  1. запустить оригинальную программу
  2. записи модифицированная версия
  3. с использованием программы командной строки, подключиться к работающей JVM и заменить существующий метод

так, что во время выполнения, это будет происходить:

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

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

Сегодня это даже лучше день с номером 15002

Сегодня это еще лучше день с номером 15003

...

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

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

+3

Можете ли вы объяснить, почему вы не можете использовать шаблон стратегии (например, объект переменной, реализующий требуемую переменную)? Способы обмена звучат сложнее, чтобы достичь того, чего вы хотите. – ivy

+0

@ivy: Я мог бы использовать это, конечно, но мне просто интересно, можно ли делать то, что я описал в своем вопросе. Вы можете рассматривать это как «теоретический» вопрос каким-то образом. – darioo

+0

@ivy существует механизм для обновления текущей службы, а не для выбора между набором известных реализаций. –

ответ

35

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

+0

является надежным и подходит для производственных условий? Как и в случае горячего обновления до запуска служб без простоя? Или это действительно просто способ сократить цикл редактирования/компиляции/запуска в dev? – Kevin

+0

No- не подходит для производства – IcedDante

3

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

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

+0

Я попробую JPDA один день. То, что я имел в виду, было наоборот.JVM не отслеживает изменения файла класса, но вы передаете JVM непосредственно «новой» версии одного класса. – darioo

14

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

9

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

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

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

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

+0

Plus 1, потому что вы упоминаете JPDA, который является фактическим интерфейсом JVM, используемым инструментами. Теперь я просто хочу увидеть минимальный исполняемый пример :-) –

2

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

2

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

4

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

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

Смежные вопросы