Динамическое выполнение кода - PullRequest
9 голосов
/ 12 ноября 2010

Подобно динамическому SQL, в котором строка выполняется как SQL во время выполнения, можем ли мы запустить Java-код динамически? Как я возвращаю строку, которая является кодом Java, а затем выполняю во время выполнения. Возможно ли это?

Ответы [ 7 ]

15 голосов
/ 12 ноября 2010

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

Самый простой способ выполнить код, предоставленный во время выполнения, - это использовать * 1006.* Rhino JavaScript engine .

Обе эти опции были только в Java 6, хотя я полагаю, что интерфейс сценариев существовал и раньше, поэтому вы можете использовать Rhino в более ранней JRE, если загрузите и добавите его впуть к классам.

6 голосов
/ 12 ноября 2010

Javassist

Вам потребуется использовать библиотеку манипулирования байт-кодом, такую ​​как Javassist ( Wikipedia ), чтобы запустить произвольную строку, которая предоставляется во время выполнения,Javassist позволяет создавать CtClass на основе строки, представляющей исходный код;и затем может превратить это в скомпилированный объект Class через определенный загрузчик классов, чтобы класс был доступен для вашего приложения.Другие библиотеки должны были бы сделать что-то похожее на эти два шага, чтобы добиться того же.

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

4 голосов
/ 12 ноября 2010

Вы также можете посмотреть на поддержку сценариев Java 6: http://download.oracle.com/javase/6/docs/technotes/guides/scripting/programmer_guide/index.htm

Вот версия hello world, которая создает массив строк и печатает первый:

<code>
import javax.script.*;
public class EvalScript { 
    public static void main(String[] args) throws Exception {
        ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
        engine.eval("var a=java.lang.reflect.Array.newInstance(java.lang.String, 1);a[0]='Hello World';print(a[0])");
    }
}
4 голосов
/ 12 ноября 2010

Если вы хотите сделать больше, чем динамически вызывать существующий метод, вам может понадобиться скомпилировать вашу строку в байт-код.Простой способ сделать это - включить jar компилятора Eclipse / JDT в ваш classpath, а затем использовать его для компиляции вашей String в класс, который затем можно загрузить.

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

Помните, что, как и в случае с SQL, вы должны быть осторожны спредотвратить проблемы с внедрением кода, если любая из строк содержит данные, указанные пользователем.

3 голосов
/ 12 ноября 2010

Да, это возможно.Посмотрите на API компилятора Java.Посмотрите здесь:

http://download.oracle.com/javase/6/docs/api/javax/tools/JavaCompiler.html

3 голосов
/ 12 ноября 2010

Взгляните на Beanshell . Он предоставляет интерпретатор с синтаксисом, подобным Java.

0 голосов
/ 12 ноября 2010

Да, используя отражение: учебник

И еще один учебник здесь от IBM

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...