Как я могу скомпилировать и развернуть Java-класс во время выполнения?

Я нахожусь в процессе написания механизма правил, который выполняет простые назначения, как определено условными конструкциями. Обязательным условием проекта является наличие правил в формате XML. Я смоделировал мою схему XML, чтобы она напоминала простые блоки кода. Я хочу проанализировать XML и затем преобразовать его в код Java. Затем я хочу скомпилировать (и запустить) этот код во время выполнения. Это будет означать, что мой механизм правил больше не действует как интерпретатор, а выполняет собственный Java-байт-код.

Я выяснил стадию синтаксического анализа и более или менее фазу генерации Java-кода. Теперь я хотел бы выяснить последний этап - компиляция на этапе выполнения.

Следующий поток: Компилировать в байт-код Java (без использования Java). Мне стало известно о следующих возможных решениях:

Я хотел бы сравнить их, а также другие предложения для решения компиляции Java на этапе выполнения.

7 ответов

Решение

Используйте API компилятора Java 6.

Вы можете преобразовать его в код Clojure, и компилятор Clojure превратит его в байт-код для вас.

Вот утилита компиляции Java, вы можете скомпилировать свой код во время выполнения без какого-либо инструмента байт-кода

http://code.google.com/p/compilation-toolbox/

Javassist - это почти полный компилятор Java, написанный на Java, и он полностью сделан из Java. Вы не можете дать ему целый файл.java сразу, но вы можете дать ему строку кода для отдельных функций и добавить их в тот же объект CtClass, который становится байт-кодом, а затем java.lang.Class.

Я только что выпустил версию 0.1 GigaLineCompile, которая использует Javassist (компилятор) и Beanshell (интерпретатор) вместе и дает вам контроль над тем, какой код оптимизировать и когда. В более поздних версиях он будет меняться между Javassist и Beanshell с меньшей степенью детализации, поэтому, если у вас есть много строк кода, которые совместно используют некоторые подстроки, подстроки будут скомпилированы, а другие части будут выполняться в beanshell. Он в основном полезен для искусственного интеллекта, который генерирует код Java, но также является альтернативой Clojure или крайностям только Javassist/Beanshell.

Javassist, Beanshell и GigaLineCompile можно загрузить (с источником) здесь: http://sourceforge.net/projects/gigalinecompile

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

Избавьте себя от хлопот и используйте BeanShell, как указано здесь. Выполнение Java-кода, приведенного в текстовом файле.

Что такое BeanShell?

BeanShell - это небольшой бесплатный встраиваемый интерпретатор исходного кода Java с функциями языка объектных сценариев, написанный на Java. BeanShell динамически выполняет стандартный синтаксис Java и дополняет его обычными сценариями, такими как свободные типы, команды и замыкания методов, такие как в Perl и JavaScript.

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

BeanShell небольшой и встраиваемый, поэтому вы можете вызывать BeanShell из ваших Java-приложений для динамического выполнения Java-кода во время выполнения или для обеспечения расширяемости в ваших приложениях. В качестве альтернативы вы можете использовать автономные скрипты BeanShell для манипулирования Java-приложениями; работа с объектами Java и API динамически. Поскольку BeanShell написан на Java и работает в той же виртуальной машине, что и ваше приложение, вы можете свободно передавать ссылки на "живые" объекты в сценарии и возвращать их в качестве результатов.

Короче говоря, BeanShell - это динамически интерпретируемая Java, а также язык сценариев и гибкая среда, объединенные в один чистый пакет.

Вы можете раскошелиться на такой процесс

Process p = Runtime.getRuntime().exec("java -classpath "..." SomeClassContainingMain ...other arguments);       

        //you need to consume the outputs of the command if output/error is large otherwise the process is going to hang if output/error buffer is full. and create a seperate thead for it (not created here).
        log.debug("PROCESS outputstream : " + p.getInputStream() );
        log.debug("PROCESS errorstream : " + p.getErrorStream());           
    p.waitFor(); // Wait till the process is finished

и может скомпилировать и запустить его.

Другие вопросы по тегам