Java

Java 8 Tutorial: Giới thiệu Nashorn Engine

Java 8 Tutorial: Giới thiệu Nashorn Engine

1.Giới thiệu

Sự ra đời của Java 8 trong năm 2014 này có rất nhiều thay đổi mới trong đó chúng ta phải kể đến việc phát triển Nashorn Engine nhằm thay thế cho Rhino Engine cũ và tích hợp chúng vào trong JVM để làm cho lập trình Java và javascript trở nên dễ dàng hơn và có hiệu năng cao hơn. trong bài này tôi giới thiệu với các bạn về Nashorn và cách sử dụng chúng trong Java 8.

2. Nashorn là gì?

Nashorn là một engine thực thi javascript mới, tương tự như các engine V8 của trình duyệt Chrome hay SquirrelFish engine của WebKit. Từ năm 1997, Java đã có thể làm việc (hạn chế) với javascript thông qua engine Rhino; trong Java 7, việc thực thi javascript trên JVM thông qua cơ chế invokeDynamic. Với Java 8, bằng việc tích hợp hoàn toàn Nashorn vào JVM, lập trình viên có thể sử dụng javascript khai thác các thư viện có sẵn của java và ngược lại. Theo thử nghiệm thì Nashorn chạy nhanh gấp 5 lần Rhino và đòi hỏi ít bộ nhớ hơn.

3. Tại sao Nashorn lại được phát triển?

Nó được phát triển để thay thế cho javascript engine đã quá cũ trong jvm từ năm 1997
Tạo ra cầu nối giữa java và javascript. ( cây cầu này được tạo ra trong môi trường JVM)
Giải quyết vấn đề không tương thích giữa java và javascript.
Nâng cao performance của việc thực thi javascript trong java. thay thế cho Rhino engine đã quá lỗi thời.
Bằng việc tích hợp javascript trong java code. bạn có thể chỉnh sửa, mở rộng, sử dụng các ưu điểm của các api có sẵn trong java. (nghĩa là bạn có thể truy cập và sử dụng các thư viện có sẵn trong java để thực thi từ javascript)

4. Script engine & script language là gì?

Scripting engine: là một trình thông dịch của các ngôn ngữ scripting. được viết sẵn trong java JDK nằm trong javax.script package.
Script language: là ngôn ngữ lập trình có hỗ trợ có khả năng viết các script (php,ruby, python , javascript..). đối với các ngôn ngữ cần biên dịch như java, .net thì cần phải có trình biên dịch dịch ra mã bytecodes trước khi chúng được chạy. còn đối với script language thì chúng chỉ được dịch tại thời điểm chạy. bởi một script engine.
Hầu hết các script language đều là có khai báo các kiểu dữ liệu động. (nghĩa là có thể khai báo các kiểu dữ liệu khác nhau cho cùng một biến., và khi bạn tạo một biến cũng không cần phải khai báo kiểu dữ liệu. chỉ khi nào bạn chạy nó thì mới cần khai báo.).
Tài liệu “Java Specification Request (JSR) 223″ có mô tả rõ những vấn đề gặp phải khi tích hợp java và javascript trong java. http://jcp.org/en/jsr/detail?id=223

5. Javascripting API:

Nó là sự cài đặt JSR 223 trong ứng dụng java. Nhằm để nhúng javascript vào trong java.

6. Nashorn engine:

Là một javascript engine viết dựa trên tài liệu mô tả của ECMAScript (javascript) engine được tích hợp trong JDK. nó đã được phát triển đầy đủ bởi oracle và được tích hợp trong jdk8. tương thích hoàn toàn với javascript.

7. Làm thế nào để sử dụng Nashorn?

Cần import thư viện javax.script.*; để sử dụng script engine trong java.
khởi tạo một đối tượng Nashorn Script Engine sử dụng ScriptEngineManager của java.
sử dụng script engine vừa tạo để thực hiện một đoạn mã javascript.

VD :

 import javax.script.*;
 public class EvalScript { 
 public static void main(String[] args) throws Exception { 
 ScriptEngineManager manager = new ScriptEngineManager(); 
 ScriptEngine engine = manager.getEngineByName("nashorn");
    // evaluate JavaScript code
   engine.eval("print('Hello, World')");
 }}

 

8. Các cách sử dụng các thư viện có sẵn của Java bằng script engine

sử dụng các class của Java.

import javax.script.*;
public class EvalFile {
public static void main(String[] args) throws Exception {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("nashorn");

    // evaluate JavaScript code
    engine.eval(new java.io.FileReader("script.js"));
}}

Đưa một object của Java thành một biến global của script engine:

import javax.script.*; 
import java.io.*;
public class ScriptVars { public static void main(String[] args) throws Exception {
ScriptEngineManager manager = new ScriptEngineManager(); 
ScriptEngine engine =  manager.getEngineByName("nashorn");

    // create File object
    File f = new File("test.txt");
    // expose File object as a global variable to the engine
    engine.put("file", f);
    // evaluate JavaScript code and access the variable
    engine.eval("print(file.getAbsolutePath())");
}}

Thực thi một Script function từ script engine.

  import javax.script.*;
  public class InvokeScriptFunction { 
  public static void main(String[] args) throws Exception { 
  ScriptEngineManager manager = new ScriptEngineManager();
  ScriptEngine engine = manager.getEngineByName("nashorn");

    // evaluate JavaScript code that defines a function with one parameter
    engine.eval("function hello(name) { print('Hello, ' + name) }");

    // create an Invocable object by casting the script engine object
    Invocable inv = (Invocable) engine;

    // invoke the function named "hello" with "Scripting!" as the argument
    inv.invokeFunction("hello", "Scripting!");
}
}

Thực thi một script method của Object

 import javax.script.*;
 public class InvokeScriptMethod { 
 public static void main(String[] args) throws Exception {
 ScriptEngineManager manager = new ScriptEngineManager();
 ScriptEngine engine = manager.getEngineByName("nashorn");

    // evaluate JavaScript code that defines an object with one method
    engine.eval("var obj = new Object()");
    engine.eval("obj.hello = function(name) { print('Hello, ' + name) }");

    // expose object defined in the script to the Java application
    Object obj = engine.get("obj");

    // create an Invocable object by casting the script engine object
    Invocable inv = (Invocable) engine;

    // invoke the method named "hello" on the object defined in the script
    // with "Script Method!" as the argument
    inv.invokeMethod(obj, "hello", "Script Method!");
   }}

chú ý: không phải tất các các script engine đều được cài đặt Invocable interface. trong ví dụ trên thì chúng ta sử dụng nashorn engine đã được cài đặt invocabkle interface.

Cài đặt một Java interface bằng script functions:

   public class ImplementRunnable {
   public static void main(String[] args) throws Exception {
   ScriptEngineManager manager = new ScriptEngineManager();
   ScriptEngine engine = manager.getEngineByName("nashorn");

    // evaluate JavaScript code that defines a function with one parameter
    engine.eval("function run() { print('run() function called') }");

    // create an Invocable object by casting the script engine object
    Invocable inv = (Invocable) engine;

    // get Runnable interface object
    Runnable r = inv.getInterface(Runnable.class);

    // start a new thread that runs the script
    Thread th = new Thread(r);
    th.start();
    th.join();
} }

Cài đặt một Java interface bằng script object methods.

  import javax.script.*;
  public class ImplementRunnableObject {
  public static void main(String[] args) throws Exception {
  ScriptEngineManager manager = new ScriptEngineManager();
  ScriptEngine engine = manager.getEngineByName("nashorn");

    // evaluate JavaScript code that defines a function with one parameter
    engine.eval("var obj = new Object()")
    engine.eval("obj.run = function() { print('obj.run() method called') }");

    // expose object defined in the script to the Java application
    Object obj = engine.get("obj");

    // create an Invocable object by casting the script engine object
    Invocable inv = (Invocable) engine;

    // get Runnable interface object
    Runnable r = inv.getInterface(obj, Runnable.class);

    // start a new thread that runs the script
    Thread th = new Thread(r);
    th.start();
    th.join();
 } }

Sử dụng biến trong các phạm vi khác nhau.

  public class MultipleScopes { 
  public static void main(String[] args) throws Exception {
  ScriptEngineManager manager = new ScriptEngineManager(); 
  ScriptEngine engine = manager.getEngineByName("nashorn");

    // set global variable
    engine.put("x","hello");

    // evaluate JavaScript code that prints the variable (x = "hello")
    engine.eval("print(x)");

    // define a different script context
    ScriptContext newContext = new SimpleScriptContext();
    newContext.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE);
    Bindings engineScope = newContext.getBindings(ScriptContext.ENGINE_SCOPE);

    // set the variable to a different value in another scope
    engineScope.put("x", "world");

    // evaluate the same code but in a different script context (x = "world")
    engine.eval("print(x)", newContext);
} }

 

9. sử dụng truy cập đến các thư viện có sẵn của Java trong script engine

primitive data type:

   var ArrayList = Java.type("java.util.ArrayList"); 
   var intType = Java.type("int");
   var StringArrayType = Java.type("java.lang.String[]"); 
   var int2DArrayType = Java.type("int[][]");

* Object data type:

      var ArrayList = Java.type("java.util.ArrayList");
      var defaultSizeArrayList = new ArrayList;
      var customSizeArrayList = new ArrayList(16);

Truy cập inner class bằng $ sign:

var Float = Java.type("java.awt.geom.Arc2D$Float");

sử dụng import class or package:

   // Load compatibility script 
   load("nashorn:mozilla_compat.js");
   // Import the java.awt package 
   importPackage(java.awt); 
 // Import the java.awt.Frame class
  importClass(java.awt.Frame); 
  // Create a new Frame object 
  var frame = new java.awt.Frame("hello"); 
  // Call the setVisible() method 
  frame.setVisible(true);
  // Access a JavaBean property 
  print(frame.title);

Nashorn thực sự là một cầu nối giữa Java và javascript. Nó thực sự đã làm cho việc thực thi nhiều ngôn ngữ trong Java trở nên dễ dàng hơn, nâng cao hiệu năng xử lý javascript trong Java

Nguồn:

http://tech.blog.framgia.com/vn/?p=2857

http://txnam.net/nhung-diem-moi-trong-java-8.html

Advertisements

1 thought on “Java 8 Tutorial: Giới thiệu Nashorn Engine”

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s