Создание динамических приложений с помощью javax.tools

Библиотека

Пакет javax.tools, добавленный в Java SE 6 как стандартный API для компиляции исходного кода Java, позволяет добавлять динамическую функциональность для расширения статических приложений. Эта статья представляет обзор основных классов пакета и показывает, как использовать их для компиляции исходного кода Java из Java-объектов String, StringBuffer или CharSequence вместо файлов. Затем этот фасад используется для построения интерактивного приложения для построения графиков, которое позволяет пользователю задать числовую функцию y = f(x) с помощью любого правильного числового Java-выражения. В конце обсуждаются возможные угрозы безопасности, связанные с динамической компиляцией исходного кода, и способы для устранения этих рисков.

Идея расширения приложений через компиляцию и загрузку Java-расширений не нова, и существует несколько каркасов, поддерживающих такую функциональность. Технология серверных Java-страниц (JavaServer Pages — JSP) в платформе Java Enterprise Edition (Java EE) – это широко известный пример динамического каркаса, которые генерирует и компилирует Java-классы. Транслятор JSP трансформирует .jsp файлы в Java-сервлеты (servlets), используя промежуточные файлы исходного кода, которые затем компилируются JSP-процессором и загружаются в Java EE-контейнер Java-сервлетов. Компиляция часто выполняется прямым вызовом компилятора javac, который требует установленного комплекта Java-разработчика (Java Development Kit — JDK), или вызовом класса com.sun.tools.javac.Main, который можно найти в JAR-архиве tools.jar от Sun. Лицензия Sun позволяет распространять файл tools.jar с полной версией среды исполнения Java (Java Runtime Environment — JRE). Другие способы реализовать подобные динамические возможности включают в себя использование языков динамических сценариев (таких как JavaScript или Groovy), которые интегрируются с языком реализации приложения (см. раздел Ресурсы) или написание специального доменно-ориентированного языка и связанного с ним интерпретатора или компилятора.

Другие среды (такие как NetBeans и Eclipse) допускают расширения, написанные непосредственно на языке Java, но подобные системы требуют внешней статической компиляции и управления исходным и бинарным Java-кодом и его артефактами. Технология Apache Commons JCI предоставляет механизм для компиляции и загрузки Java-классов в работающее приложение. Технологии Janino и Javassist также предоставляют сходные динамические возможности, хотя Janino ограничена конструкциями языка до версии Java 1.4, а Javassist работает не на уровне исходного кода, а на уровне абстракции Java-классов. В разделе Ресурсы приведены ссылки на эти проекты. Однако, поскольку Java-разработчики уже привыкли писать на языке Java, система, которая позволяет просто генерировать исходный код Java на лету, а затем компилировать и загружать, обещает самый простой путь обучения и максимальную гибкость.

Преимущества использования javax.tools

Использование javax.tools предоставляет следующие преимущества:
Это одобренное расширение платформы Java SE, а, значит, это стандартный API, разработанный в рамках Java Community Process (JSR 199). API-интерфейс com.sun.tools.javac.Main по спецификации не является частью документированного API платформы Java и необязательно имеется в JDK от других поставщиков; также не гарантировано наличие этого PI в будущих версиях Sun JDK.

При этом вы используете то, что знаете: исходный код Java, а не байт-код. Можно создавать правильные Java-классы, генерируя соответствующий исходный код Java, без изучения более сложных правил правильного байт-кода или новой объектной модели классов, методов, объявлений и выражений.

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

Он переносим между текущими и будущими реализациями JDK версии 6 и выше от различных производителей.

Он использует проверенную версию компилятора Java.

В отличие от систем, основанных на интерпретации, загруженные классы могут пользоваться всеми оптимизациями, выполняемыми JRE во время исполнения.