Изменение метода во время выполнения с помощью механизма "горячей" замены
предположим, что у нас есть тривиальная программа 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);
}
есть что-то похожее на горячая замена кода Эрланга где я могу сделать это:
- запустить оригинальную программу
- пишем модифицированной версии
- использование программа командной строки, подключитесь к запущенной JVM и замените существующий метод
так, что во время выполнения, это будет происходить:
Сегодня хороший день с номером 15000
Сегодня хороший день с номером 15001
сегодня еще более приятный день с номером 15002
сегодня еще более приятный день с номером 15003
...
предположим, что выше программа автономный, работает в стандартной среде Java SE, нет ничего другого на classpath, так что это почти программа Hello world style.
примечание: Я знаю, что такие технологии, как байт-код манипуляции (cglib),aspectJ,jRebel,протокола, hotswapping методов в Java EE и др. существуют, но это не то, о чем я думаю. Подумай об Эрланге.
7 ответов:
вы можете либо использовать open-source HotSpot VM или коммерческого JRebel IDE плагин, чтобы легко достичь своей цели (сравнение в таблице здесь).
вы можете сделать это с помощью загрузчиков классов. Например, если вы знакомы с контейнерами сервлетов, такими как tomcat, которые перезагружают страницы при их изменении в процессе разработки. Вот это отличное объяснение создания динамического кода в Java. Это не только объясняет загрузку, но и компиляцию исходного кода на лету. Вы должны быть в состоянии применить концепции, описанные в любой стратегии перезагрузки кода, который вы хотите использовать.
Я использовал этот hotswap ant task во многих проектах. Целевое приложение java может быть запущено через Ant, Eclipse, командную строку или любым другим способом, если оно запускается в режиме отладки с открытым соответствующим портом. На связанной странице приведены инструкции о том, как это сделать с помощью Ant.
любое количество классов может быть hotswapped до тех пор, пока изменения не являются структурными. Метод изменения тела, как правило, hotswap с легкостью. Код может быть hotswapped, запустив муравей скрипт через оболочку или затмение.
на работе я использую скрипт, который автоматически изменяет код hotswaps, сравнивая временные метки в файлах классов. Это похоже на пример на странице проекта, который показывает простой пример, что только hotswaps изменил классы.
дополнительное Примечание: это использует JPDA.
немного старый пост, но, надеюсь, кто-то найдет это полезным:
Я нашел относительно новый Агент Hotswap хорошо документирована и многофункциональна (и лучше всего,open source).
вы можете сделать это через интерфейс JPDA (Java Platform Debugger Architecture):http://download.oracle.com/javase/1.4.2/docs/guide/jpda/enhancements.html#hotswap
Это не автоматически, как в случае Erlang-JVM не отслеживает путь к классу для изменений в файлах классов, а затем перезагружает и повторно связывает их, если они изменены, по довольно очевидным причинам (Java была разработана для веб-развертывания, вы не хотите опрашивать HTTP-URL для изменений).
Как насчет каталога? Горячая замена-это своего рода" встроенный " в спецификацию - я думаю, что это было бы одним из возможных решений.
вы можете использовать шаблон разработки стратегии, поэтому у вас есть объект для манипулирования, а не метод, и протокол для связи с программой, чтобы сказать ему использовать заданное имя класса в качестве класса объекта стратегии.
Comments