BeanShell. Выполняем Java код на лету

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

Так как непосредственная реализация подобного функционала сопряжена с определёнными сложностями, лучшим решением будет применение готовых инструментов. Наиболее известным из них является библиотека BeanShell (ссылка на официальный сайт в конце статьи).

Ядро библиотеки – класс Interpreter и его метод eval, который принимает в качестве параметра строку с программным кодом на языке Java и выполняет его.

Основы выполнения кода на лету

Для того чтобы выполнить код необходимо:

  • Создать строку с текстом кода;
  • Создать объект класса Interpreter;
  • Передать строку с кодом в метод eval.

Ниже приведён простейший пример выполнения кода во время работы программы.

В результате на консоль будет выведено сообщение «Hello, World!»

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

Например. Если первую строку вышеприведённого примера исказить вот так:

В консоли будет выведено сообщение об ошибке:

Sourced file: inline evaluation of: System.out1.println(«Hello World!»);» : No static field or inner class: out1 of class java.lang.System

Выполнение на лету сложных конструкций

Возможности библиотеки BeanShell не исчерпываются только выполнением отдельных операторов. В строке кода может содержаться и гораздо более сложная логика, даже включающая классы.

При этом сам алгоритм выполнения кода остаётся неизменным. Если переписать строку кода примера следующим образом:

Будет вначале создан объект класса TestClass, затем вызван его метод run и на консоль будет выведено сообщение «Run method of class!».

Обмен данными с основной программой

Рассмотрим следующий пример. Модифицируем предыдущий пример кода так чтобы метод run класса TestClass возвращал целочисленное значение и присвоим это значение некоторой переменной.

Для того чтобы получить значение из переменной b необходимо воспользоваться методом get класса Interpreter, который возвращает значение переменной по её имени в формате Object.

В результате переменная c будет иметь значение 6.

Передача значений в переменные, объявленные в выполняемом коде, производится с помощью метода set. Однако процесс передачи переменных имеет ряд особенностей.

Дело в том, что при передаче значения обратиться к переменной напрямую, как это было при получении, нельзя. Такая возможность не поддерживается. Вместо этого значение передаётся в именованный параметр и уже оттуда в саму переменную. Именно в такой параметр и передаёт значение метод set.

Объявляем параметр в строке с кодом. Для примера назовём его просто param.

Данный параметр передаётся в переменную p, которая, в свою очередь, передаётся в метод run класса TestClass.

Передадим в параметр некоторое значение. Например, число 6.

Выполним код из строки и получим значение переменной содержащей результат, как в предыдущем примере.

В итоге значение переменной c будет равно 7.

Резюме

Библиотека BeanShell не блещет разнообразием всевозможных классов (чего нельзя сказать о пространстве имён System.CodeDom.Compiler в C#). Но, несмотря на это она предоставляет разработчику очень мощный инструментарий для расширения возможностей по созданию приложений. Причём он выполнен предельно компактно и лаконично. Ничего лишнего. Только нужный функционал.

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

Однако даже если речь идёт о более простых задачах, она станет ценным помощником  везде, где необходимо выполнять код непосредственно во время работы программы.

Ссылки:

BeanShell. Официальный сайт проекта.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *