0,0
рейтинг
30 сентября 2013 в 21:03

Разработка → Введение в Nashorn из песочницы tutorial

Введение


imageNashorn* — движок JavaScript, разрабатываемый полностью на языке программирования Java компанией Oracle. Основан на Da Vinci Machine (JSR 292) и будет доступен в составе Java 8 (релиз которой ожидается в марте 2014 года). Стоит отметить что выполнение JavaScript (и поддержка скриптов в целом) была уже в Java 6, но в ней использовался движок Rhino, также написанный на Java, но поддерживаемый Mozilla Foundation.

О списке нововведений в Java 8 уже писали ранее. В данной статье будет приведена пара простых примеров, которая даст вам представление об использовании Nashorn.


Применение


Зачем нужен JavaScript в Java? Например:


Примеры использования


Подготовительный этап

Устанавливаем JDK 8 Early Access. Далее по тексту подразумевается что команды javac и java выполняются для Java 8.

Hello, World!

import javax.script.*;

public class EvalScript {
    public static void main(String[] args) throws Exception {
        // create a script engine manager
        ScriptEngineManager factory = new ScriptEngineManager();
        // create a Nashorn script engine
        ScriptEngine engine = factory.getEngineByName("nashorn");
        // evaluate JavaScript statement
        try {
            engine.eval("print('Hello, World!');");
        } catch (final ScriptException se) { se.printStackTrace(); }
    }
}

Компилируем класс:
./javac EvalScript.java 

И выполняем его:
./java EvalScript

Видим вывод:
Hello, World!

JavaScript + Java

Nashorn позволяет использовать классы Java для создания программ. Рассмотрим следующий пример:

MyScript.js

var MyClass = Java.type("EvalScript.MyClass");
var my = new MyClass();
my.printMsg("Hello!");

EvalScript.java

import javax.script.*;
import java.io.*;

public class EvalScript {

    public static void main(String[] args) throws Exception {
        // create a script engine manager
        ScriptEngineManager factory = new ScriptEngineManager();
        // create a Nashorn script engine
        ScriptEngine engine = factory.getEngineByName("nashorn");
        // evaluate JavaScript statement
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            engine.eval(br);
        } catch (final ScriptException se) { se.printStackTrace(); }
    }

    public static class MyClass {
        public void printMsg(String msg) {
            System.out.println("printMsg : "+msg);
        }
    }
}

Для примера я создал свой внутренний класс (что не является ограничением, я мог бы создать и отдельный класс), и вызвал его из JavaScript кода. Осталось скомпилировать класс и запустить его передав на вход наш js-код:
./java EvalScript < MyScript.js

Видим вывод:
printMsg : Hello!


Вывод


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

Используемые материалы:





* Nashorn — немецкое слово, которое переводится на русский как «носорог», а на английский как «rhinoceros», что перекликается с Rhino, названием движка JavaScript, реализованного в Java и поддерживаемого компанией Mozilla Foundation. Rhino, в свою очередь, получил название в честь животного изображённого на обложке книги о JavaScript, выпущенной издательством O'Reilly Media.
Владимир Максименко @XupyprMV
карма
5,0
рейтинг 0,0
Пользователь
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (28)

  • +1
    Ну а по сути то, в чем разница по сравнению с Rhino. К тому же есть DynJs.
    Или это просто ребрендинг Rhino от Oracle?
    • 0
      Цель одна и та же — интерпретация JavaScript посредством JVM. Замеров производительности Rhino и Nashorn в сравнении не видел, но обещают повышение производительности в 20 раз. От DynJs как минимум выгодно отличается тем идёт out-of-the-box с JRE, но, как правильно замечает автор DynJS, его реализация — ПО с открытым исходным кодом в отличие от Nashorn.
      • 0
        Значит ли это, что в OpenJDK Nashorn не будет?
        • +1
          Судя по датам статей, на которые я дал ссылки в комментарии — будет. Интервью с разработчиком DynJS датируется октябрём 2011, а статья о Nashorn — ноябрём 2012. Извиняюсь что ввёл в заблуждение.

          https://wiki.openjdk.java.net/display/Nashorn/Main
          • 0
            Т.е. получается, что он всё-таки с открытым кодом.
        • +1
          Не будет. Потому что уж есть: openjdk.java.net/projects/nashorn/
          • 0
            Спасибо за ссылку
    • 0
      Читал, что оно будет использовать новые возможности JVM. Rhino в сущности интерпретатор, а эта штука сможет использовать JIT компиляцию JVM для динамического кода. V8 навряд ли догонит, но цифры хотя бы одного порядка должны быть.
      • 0
        говорят что в синтетических тестах не догоняет, на «реальных» приложениях как они выразились — одно и то же.
  • –3
    >Зачем нужен JavaScript в Java? Например:
    >Описывать бизнес-логику на более простом чем Java языке (привлекая к этому специалистов в предметной области с базовым навыком программирования)

    Судя по листингам не проще. Реально зачем нужно? Кто пролоббировал?
    • +1
      В листингах приведен Java-код для интеграции JS-движка.

      Или вот это код сложный?
      var MyClass = Java.type("EvalScript.MyClass");
      var my = new MyClass();
      my.printMsg("Hello!");
      
      • 0
        Вот почему я так считаю. Это НЕ js, который можно проверить и отладить в браузере: здесь полно зависимостей на java-классы приложения. Это дает три проблемы:
        1) js код нужно писать зная полные имена java-классов, а их может быть много.
        2) при изменении сигнатуры классов или их переименовании, мы узнаем о проблеме только по тестам (если они есть),
        3) этот js код не поддерживает ни одна IDE

        3ий пункт можно разделить две части: когда код пишется разработчиком и когда он потом редактируется пользователем приложения по образу ручного редактирования SQL-запросов. Т.е. для пользователя нужен будет встроенный редактор такого js. Он заявлен? Почему тогда не дать пользователям писать на Java и генерить байт код «на лету»? Я понимаю, что для Java это сложнее, чем .net-аналог Reflection.Emit, но это возможно и намного проще, чем компилятор JS «c нуля».
        • 0
          Ок. Отвечу по пунктам:

          1) Знать имена java-классов и методов совершенно не нужно! Просто доступную для скриптования функциональность можно предоставить в виде глобальных js-функций и обхектов. И, разумеется, хорошая документация. Использовать Java.type по-хорошему надо только для interop — этим определенно должны заниматься не предметники, но программисты.

          Вообще я не прослеживаю в этом вопросе логики: при написании js-кода нужно знать имена java-классов, а при написании java-кода уже нет. Код что, сам пишется?

          2) Смотрите пункт 1. Документация, причем сделанная специально с расчетом на предметников. Если Вы намекаете на динамическую типизацию (мол не можем валидировать скрипт), то как в подобных случаях динамические языки себя показывают лучше (не отвлекают предметника на ненужные/непонятные ему вещи).

          3) Этот js код поддерживает любая IDE. Например, его можно редактировать в Eclpise. А если неможно постараться, можно в Eclipse вообще встроить интеграцию со своей системой.

          PS: кстати, а какой встроенный редактор для Java заявлен?
        • 0
          BTW, вместо Reflection.Emit для Java есть хорошая BCEL.
    • +1
      Лично меня пугает словосчетание «базовым навыком программирования» в фразе «привлекая к этому специалистов в предметной области с базовым навыком программирования».
      Как бы это не вылезло в «переписали код заново из-за Васи с базовым навыком программирования».
  • 0
    По мне, так это изобретение велосипеда. На JVM есть много динамических ЯП, например clojure, groovy, scala, которыми можно воспользоваться для добавления скриптовой части. Не знаю точно про скалу, но первыми двумя можно. К тому же языки активно развиваются, имеют большое сообщество, и мне кажется куда более надёжные, чем новый движок.
    • +2
      Лично пробовал проделать подобное с использованием Groovy. Работает. Groovy более приятен для пользователя и менее строг по сравнению с Java.
    • 0
      Scala отметается сразу: он не динамический, весьма сложный. Не забываем, что говорим мы о «специалистах в предметной области с базовым навыком программирования». По этой же причине отметается Clojure (еще не хватало специалистов-предметников основам ФП обучать).

      Groovy лучше, но его никто не знает. Да и язык на самом деле совсем не простой.

      А вот JS нынче знают многие. И, в случае чего, JS-код с бизнес-правилами можно с очень большой долей вероятности переиспользовать, хоть в браузере, хоть в другой системе.
      • 0
        Да, скала не динамическая, это я ошибся. Я имел ввиду возможность использовать скалу, как скриптовый язык для задание каких-то конфигураций или правил. Скалисты же гордятся, что на скале очень круто DSL'и писать, как и кложуряне.

        Ну про переиспользование в браузере — мне кажется это скорее сказки. А так я бы предпочёл использовать какое-то более хорошо документированное и известное решение, чем какой-то внутренний движок, непонятный движок. Мне кажется, что если специфическая задача, то будешь что groovy/clojure под них подпиливать, что nashorn. Т.е. есть задача «Хотим сделать удобное задание бизнес-правил.» и всё равно будешь делать свой мини-dsl, что на clojure, что на javascript.
        • 0
          Это все конечно так. Но предлагаю взглянуть на статистику: сколько людей знает (на уровне «могу что-то писать») JS, а сколько Clojure/Scala/Groovy. Думаю, эти цифры многое прояснят.

          Вообще, я не призываю использовать JS (недолюбливаю всякие server-side-js). Но все же считаю, что у JS-движка на Java найдется достаточно применений, дабы такой движок создавать.
          • +1
            Так JS движок уже был давно и до этого. У меня правда нет информации, насколько часто его использовали, так что мне казалось, что им никто не пользовался, но это возможно лишь моё неведение :) Или оракловцы сейчас будут его как-то продвигать и использовать в своих проектах, интересно.
            • 0
              такие же мысли: так и не увидел до сих пор удачного использования js движка в жава коде. Как только заходит разговор о скриптах, обычно советуют python или groovy
      • +1
        >А вот JS нынче знают многие.
        Видели какие-нибудь серьезные исследования на эту тему? Доля вопросов по js на stackoverflow не превышает долю вопросов по java: hewgill.com/~greg/stackoverflow/stack_overflow/tags/#!java+javascript
        • 0
          Вероятно Вы плохо прочитали мой комментарий — я не говорил про Java. Посмотрите на Groovy/Scala/Clojure.
    • +2
      Rhino, например, используется для компиляции coffeescript в maven-задаче с использованием официального компилятора кофескрипта: github.com/iron9light/coffeescript-maven-plugin (есть мой форк этого плагина с поддержкой более свежей версии компилятора и source maps).
      • 0
        Для less, r.js тоже самое.
  • 0
    Удалено. Перепутал кнопки «ответить» и «написать комментарий».
  • 0
    Штука хорошая, но проблема в том, что в реальных проектах нужно еще и безопасность обеспечивать, а также тонкий контроль выполнения кода. Rhino без обвязки позволяет всякие штуки типа ClassShuttrer. Плюс гибкий контроль над компиляцией кода. Стандарт jsr же все это скрывает, и делает весьма бестолковым использование js в реальных проектах.

    Сам я разрабатываю PaaS для client/server приложений на js, поэтому в теме довольно плотно нахожусь…

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