Nashorn
Legacy
Nashorn появился в JDK 8, был объявлен устаревшим в JDK 11 и удалён из JDK начиная с 15. Наличие
javax.scriptне означает, что в runtime установлен JavaScript engine.
Nashorn исполнял JavaScript внутри JVM, компилировал его в bytecode и позволял взаимодействовать с Java-объектами. Это было удобно для встроенных правил и скриптов, но создавало большую поверхность доступа к приложению.
ScriptEngine engine = new ScriptEngineManager()
.getEngineByName("nashorn");
if (engine == null) {
throw new IllegalStateException("Nashorn отсутствует в этой JVM");
}
Object result = engine.eval("40 + 2");Этот пример нужен для чтения legacy-кода, а не как рекомендация для нового проекта.
Что делать сейчас
- если скрипты не обязательны — выразить правила типизированным Java-кодом;
- если нужен JS в процессе — выбрать и явно подключить поддерживаемый движок, например GraalJS;
- если код недоверенный — предпочесть отдельный изолированный процесс/сервис;
- ограничить время, память, host access и набор передаваемых объектов.
Один ScriptEngine не следует считать потокобезопасным без гарантии конкретной реализации. Компилируемый скрипт можно кэшировать, но его контекст и изменяемые bindings требуют отдельного решения.
Ошибки
- ожидать Nashorn на новой JVM без зависимости;
- давать пользовательскому скрипту неограниченный доступ к Java API;
- выполнять скрипт без timeout;
- смешивать бизнес-контракт с деталями конкретного engine.
На собеседовании
Есть ли Nashorn в современном JDK? В составе JDK 15+ — нет.
Почему getEngineByName может вернуть null? Подходящий provider не установлен.
Главный риск встроенных скриптов? Неконтролируемый доступ к ресурсам процесса и отсутствие лимитов.
Связано: Нововведения Java 8, Компилируемые и интерпретируемые языки.