2012-02-15 7 views
2

У меня есть приложение, которое нуждается в возможности обновлять части себя (по одному классу за раз) без остановки и перезапуска. С API JavaCompiler легко создавать модифицированный исходный код класса, перекомпилировать, загружать и создавать экземпляр класса. Я могу сделать это все в памяти (без файлов, считанных с диска или сети).Динамическое обновление программы, компиляция времени выполнения и загрузчики классов

Приложение никогда не создаст экземпляр более чем одного объекта такого класса. Там будет только две или три ссылки на этот объект. Когда модифицированный класс загружается и создается экземпляр, все эти ссылки будут изменены на новый объект. Я также могу, вероятно, гарантировать, что ни один метод в затронутом классе не работает в другом потоке при загрузке измененного класса.

Мой вопрос заключается в следующем: у моего загрузчика классов возникнут проблемы с загрузкой модифицированного класса с тем же именем, что и ранее загруженный класс?

Если я не реализую кэш загруженных классов в загрузчике классов, это бы избежать проблем? Или делегирование загрузчика родительского класса по-прежнему вызывает проблему?

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

Примечание: Я посмотрел на OSGI, и, похоже, это немного больше, чем мне нужно.

+0

У меня есть что-то очень похожее на это. Вам нужно будет указать использование JDK для его компиляции, иначе вы получите ошибки с возвратом JavaCompiler. –

ответ

0

Хорошо, это должно быть Работа: при загрузке нового класса он заменит имя класса в соответствующих таблицах, а память должна быть GC'd. Тем не менее, я бы дал ему напряженный тест с реальной короткой программой, которая компилирует нетривиальный класс и заменяет его, скажем, 10 000 раз.

1

Там полезный пример по этому вопросу на http://tutorials.jenkov.com/java-reflection/dynamic-class-loading-reloading.html

Мы совсем немного динамического класса перегрузки себя (с помощью Groovy для сборников). Обратите внимание, что если у вас есть зависимости классов, вам может потребоваться перекомпилировать эти зависимости для перезагрузки. В стеках dev мы отслеживаем эти зависимости, а затем перекомпилируем, когда зависимости становятся устаревшими. В производственных стеках мы выбрали неперегружаемый ClassLoader и создаем новый ClassLoader, когда что-либо изменится. Таким образом, вы можете сделать это в любом случае.

BTW - вы можете найти GroovyScriptEngine на http://grepcode.com/file/repo1.maven.org/maven2/org.codehaus.groovy/groovy-all/1.8.5/groovy/util/GroovyScriptEngine.java#GroovyScriptEngine очень интересно, если вы хотите копать, как они это делают.

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