Реализация javascript на java

Введение в Nashorn

image

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

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

Применение

  • Описывать бизнес-логику на более простом чем Java языке (привлекая к этому специалистов в предметной области с базовым навыком программирования)
  • Обеспечить модульную, расширяемую за счёт плагинов архитектуру приложения и интеграцию в приложение ранее существующих скриптов
  • Использовать совместно с Java FX
  • Использовать в web-приложениях, различным образом

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

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

Устанавливаем 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(); >> > 
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-проект автоматизацию, которую мог бы настраивать не программист, а администратор приложения, прямо через интерфейс приложения (и при этом не требовалась бы перекомпиляция компонент приложения).

Читайте также:  Face recognition python documentation

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

Источник

Java 8 Nashorn Javascript With Examples

Twitter Facebook Google Pinterest

Learn a new Nashorn Javascript engine in java. How to integrate JavaScript in java and call methods vice versa.

1. Overview

In this tutorial, you will learn how to use javascript in java and how to integrate them with each other.

Usage of javascript in java can be done with the newly added Nashorn JavaScript engine in java 8.

This completely replaces the old version of the Rhino javascript engine and it gives 2 to 10 times better performance than the older one because it does the code compilation in memory and passes the byte code to the JVM directly.

And also it uses the dynamic loading feature is introduced in java 7 to enhance the performance and completely replaces the Rhino Engine.

Java 8 Nashorn Javascript

Let us start writing the examples using the code from the command line, java, and javascript code.

Note: Before using jjs tool, you should remember that «The jjs tool is planned to be removed from a future JDK release«

2. Nashorn jjs — Command-Line Engine

JDK 1.8 is equipped with the command line interpreter that is called «jjs«. jjs is used to run the javascript files as below.

jjs tool can be found at the location $JAVA_HOME/bin

And also jjs can be used as interactive shells such as REPL. To start a REPL, do not pass any arguments to it.

javprogramto-MacBook-Pro-2$ jjs Warning: The jjs tool is planned to be removed from a future JDK release jjs> jjs>

You can print the content on to console using print() method and it takes string content.

jjs> print("Hello World") Hello World jjs> print("welocome to javaprogramto.com blog for java 8 tutorial") welocome to javaprogramto.com blog for java 8 tutorial jjs>

3. Running js file as a shell script

As you run the shell script file from the command line like «./hello.sh» in a similar way you can run the javascript file.

Just add bang pointing to jjs location «#!$JAVA_HOME/bin/jjs»

Let us write a simple code and save it as hello.js file.

#!$JAVA_HOME/bin/jjs var greeting = "Hello World, Welcome"; print(greeting);

Now, run this script from the command line with «./hello.js» and observe the below output.

$ ./hello.js Warning: The jjs tool is planned to be removed from a future JDK release Hello World, Welcome $

Like this, you can use java code from the js file also. In the next, sections you will understand how to use java code in javascript files.

Читайте также:  Java project to exe file

4. Passing Arguments to JJS

jjs command can work with the arguments also. When you use jjs command to start the interactive mode, you can pass as many as arguments you need.

And all of the passed arguments are stored in a variable «arguments». By using this builtin keyword in javascript, you can get all of these argument values.

Note: You need to pass the double hyphen «—» after jjs command.

Let us run the sample code as «jjs — one two threee»

$ jjs -- one two threee Warning: The jjs tool is planned to be removed from a future JDK release jjs> print("given argument values are "+arguments.join(" , ")) given argument values are one , two , threee jjs>$

5. Call JavaScript from Java

Java 8 api is added with a built-in engine that is called an Embedded Script Engine which creates a runtime environment to execute the javascript code on the JVM for a dynamic language.

Use ScriptEngineManager class to get the script engines that are managed by JVM.

Next, get the nashorn script engine using getEngineByName(«nashorn») and pass the right name to it.

Finally, call eval() method to run the native javascript code from java and eval() returns an Object if you are executing arithmetic operations. In such cases, you need to use explicit type casting to the right object types. It is the time now to play with the javascript notations.

package com.javaprogramto.java8.nashorn; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; public class CallJavaScriptFromJavaExample < public static void main(String[] args) throws ScriptException < // creating java script engine ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); // getting the nashorn engine ScriptEngine nashorn = scriptEngineManager.getEngineByName("nashorn"); // evaluating the javascript statement to print nashorn.eval("print('hello , this is first javascript example in java') "); // summing 2 numbers in js from java code. Integer i = (Integer) nashorn.eval("1 + 2"); System.out.println("sum from javascript : " + i); > >
hello , this is first javascript example in java sum from javascript : 3

You can observe the output that printed the content using the javascript print() method and the addition of two numbers.

6. Exceptions from NashornScriptEngine

If you pass the invalid or wrong javascript syntax to eval() method then. it will throw a runtime exception saying «ScriptException» with different reasons.

If you miss the ending or closing quotes. for the print() method then it. will say » Missing close quote»

Warning: Nashorn engine is planned to be removed from a future JDK release Exception in thread "main" javax.script.ScriptException: :1:57 Missing close quote pirnt('hello , this is first javascript example in java) ^ in at line number 1 at column number 57 at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine.throwAsScriptException(NashornScriptEngine.java:477) at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine.compileImpl(NashornScriptEngine.java:544) at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine.compileImpl(NashornScriptEngine.java:531) at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:409) at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:162) at java.scripting/javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264) at com.javaprogramto.java8.nashorn.CallJavaScriptFromJavaExample.main(CallJavaScriptFromJavaExample.java:16) Caused by: jdk.nashorn.internal.runtime.ParserException: :1:57 Missing close quote pirnt('hello , this is first javascript example in java) ^ at jdk.scripting.nashorn/jdk.nashorn.internal.parser.Lexer.error(Lexer.java:1860) at jdk.scripting.nashorn/jdk.nashorn.internal.parser.Lexer.scanString(Lexer.java:1006) at jdk.scripting.nashorn/jdk.nashorn.internal.parser.Lexer.lexify(Lexer.java:1717) at jdk.scripting.nashorn/jdk.nashorn.internal.parser.AbstractParser.getToken(AbstractParser.java:135) at jdk.scripting.nashorn/jdk.nashorn.internal.parser.AbstractParser.nextToken(AbstractParser.java:216) at jdk.scripting.nashorn/jdk.nashorn.internal.parser.AbstractParser.nextOrEOL(AbstractParser.java:173) at jdk.scripting.nashorn/jdk.nashorn.internal.parser.AbstractParser.next(AbstractParser.java:160) at jdk.scripting.nashorn/jdk.nashorn.internal.parser.Parser.scanFirstToken(Parser.java:293) at jdk.scripting.nashorn/jdk.nashorn.internal.parser.Parser.parse(Parser.java:323) at jdk.scripting.nashorn/jdk.nashorn.internal.parser.Parser.parse(Parser.java:285) at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.Context.compile(Context.java:1500) at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.Context.compileScript(Context.java:1467) at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.Context.compileScript(Context.java:750) at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine.compileImpl(NashornScriptEngine.java:542) . 5 more

If you pass the invalid method name then it will give an error.

Warning: Nashorn engine is planned to be removed from a future JDK release Exception in thread "main" javax.script.ScriptException: ReferenceError: "invoke" is not defined in at line number 1 at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine.throwAsScriptException(NashornScriptEngine.java:477) at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:461) at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:413) at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:409) at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:162) at java.scripting/javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264) at com.javaprogramto.java8.nashorn.CallJavaScriptFromJavaExample.main(CallJavaScriptFromJavaExample.java:18) Caused by: :1 ReferenceError: "invoke" is not defined at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.ECMAErrors.error(ECMAErrors.java:57) at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.ECMAErrors.referenceError(ECMAErrors.java:319) at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.ECMAErrors.referenceError(ECMAErrors.java:291) at jdk.scripting.nashorn/jdk.nashorn.internal.objects.Global.__noSuchProperty__(Global.java:1616) at jdk.scripting.nashorn.scripts/jdk.nashorn.internal.scripts.Script$Recompilation$1$\^eval\_/0x00000008001dc040.:program(:1) at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:655) at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:513) at jdk.scripting.nashorn/jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:527) at jdk.scripting.nashorn/jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:456) . 5 more

7. Call Java From JavaScript

In the previous section, we. have seen how to call native javascript code from java classes.

Читайте также:  Сложные задачи на javascript

Next, let us see how to use java classes in JavaScript files.

Let us create a sample javascript code that uses the java class BigDecimal.

Call Java.type() method to use the java classes from javascript and pass the class name along with the package name. Then that class is loaded into the nashorn engine and returns its object. So, we’ve stored it in the var variable.

Calling Java Methods from JavaScript Example:

var BigDecimalClass = Java.type('java.math.BigDecimal'); function calculate(amount, percentage) < var result = new BigDecimalClass(amount).multiply(new BigDecimalClass(percentage)).divide( new BigDecimalClass("100"), 2, BigDecimalimalClass.ROUND_HALF_EVEN); return result.toPlainString(); > var result = calculate(1000,20); print("Final value : "+result);
$ jjs sample.js Final value : 200.00 $

Any java class can be used inside the javascript code such as adding key-value pairs. to HashMap.

Save the below file as hashmap.js

Example to use HashMap from Javascript:

var HashMap = Java.type('java.util.HashMap') var map = new HashMap() map.put('hello', 'world') print("map values : "+map)

8. Conclusion

In this article, you’ve seen the new javascript engine nashorn added in java 8.

Examples on how to call javascript from java and vice versa.

Now, you can call javascript functions, pass bindings, and use java objects from both languages using jjs tool.

All examples shown are over GitHub.

Источник

Оцените статью