Chapter 17. The Java Scripting API

The Java Scripting API, introduced in Java SE 6, provides support that allows Java applications and scripting languages to interact through a standard interface. This API is detailed in JSR 223, “Scripting for the Java Platform,” and is contained in the javax.script package found within the java.scripting module.

Scripting Languages

Several scripting languages have script engine implementations available that conform to JSR 223. See “Scripting Languages Compatible with JSR-223” in Appendix B for a subset of these supported languages.

Script Engine Implementations

The ScriptEngine interface provides the fundamental methods for the API. The ScriptEngineManager class works in conjunction with this interface and provides a means to establish the desired scripting engines to be utilized.

Embedding Scripts into Java

The scripting API includes the ability to embed scripts and/or scripting components into Java applications.

The following example shows two ways to embed scripting components into a Java application: (1) the scripting engine’s eval method reads in the scripting language syntax directly, and (2) the scripting engine’s eval method reads the syntax in from a file:

import java.io.FileReader;
import java.nio.file.Path;
import java.nio.file.Paths;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

public class HelloWorld {
  public static void main(String[] args) throws
      Exception {
    ScriptEngineManager m
        = new ScriptEngineManager();
    // Sets up Nashorn JavaScript Engine
    ScriptEngine e = m.getEngineByExtension("js");
    // Nashorn JavaScript syntax
    e.eval("print ('Hello, ')");
    // world.js contents: print('World!
');
    Path p1 = Paths.get("/opt/jpg2/world.js");
    e.eval(new FileReader(p1.toString()));
  }
}

$ Hello, World!

Invoking Methods of Scripting Languages

Scripting engines that implement the optional Invocable interface provide a means to invoke (execute) scripting language methods that the engine has already evaluated (interpreted).

The following Java-based invokeFunction() method calls the evaluated Nashorn scripting language function greet(), which we have created:

ScriptEngineManager m = new ScriptEngineManager();
ScriptEngine e = m.getEngineByExtension("js");
e.eval("function greet(message) {print(message)}");
Invocable i = (Invocable) e;
i.invokeFunction("greet", "Greetings from Mars!");

$ Greetings from Mars!

Accessing and Controlling Java Resources from Scripts

The Java Scripting API provides the ability to access and control Java resources (objects) from within evaluated scripting language code. The script engines use key-value bindings.

Here, the evaluated Nashorn JavaScript makes use of the nameKey/world binding and reads in (and prints out) a Java data member from the evaluated scripting language:

ScriptEngineManager m = new ScriptEngineManager();
ScriptEngine e = m.getEngineByExtension("js");
e.put("nameKey", "Gliese 581 c");
e.eval("var w = nameKey" );
e.eval("print(w)");

$ Gliese 581 c

By utilizing the key-value bindings, you can make modifications to the Java data members from the evaluated scripting language:

ScriptEngineManager m = new ScriptEngineManager();
ScriptEngine e = m.getEngineByExtension("js");
List<String> worldList = new ArrayList<>();
worldList.add ("Earth");
worldList.add ("Mars");
e.put("nameKey", worldList);
e.eval("var w = nameKey.toArray();");
e.eval(" nameKey.add ("Gliese 581 c")");
System.out.println(worldList);

$ [Earth, Gliese 581 c]

Setting Up Scripting Languages and Engines

Before using the Scripting API, you must obtain and set up the desired script engine implementations. Many scripting languages include the JSR-223 scripting engine with their distribution, either in a separate JAR or in their main JAR, as in the case of JRuby.

Scripting Language Setup

Here are the steps for setting up the scripting language:

  1. Set up the scripting language on your system. “Scripting Languages Compatible with JSR-223” in Appendix B contains a list of download sites for some supported scripting languages. Follow the associated installation instructions.

  2. Invoke the script interpreters to ensure that they function properly. There is normally a command-line interpreter, as well as one with a graphical user interface.

For JRuby (as an example), the following commands should be validated to ensure proper setup:

jruby [file.rb] //Command line file
jruby.bat //Windows batch file

Scripting Engine Setup

Here are the steps for setting up the scripting engine:

  1. Determine if your scripting language distribution includes the JSR-223 scripting API engine in its distribution. If it is included, steps 2 and 3 are not necessary.

  2. Download the scripting engine file from the engine’s website.

  3. Place the downloaded file into a directory and extract it to expose the necessary JAR. Note that the optional software (opt) directory is commonly used as an installation directory.

Tip

To install and configure certain scripting languages on a Windows machine, you may need a minimal POSIX-com⁠pliant shell, such as MSYS or Cygwin.

Scripting Engine Validation

Validate the scripting engine setup by compiling and/or interpreting the scripting language libraries and the scripting engine libraries. The following is an older version of JRuby where the engine was available externally:

javac -cp c:optjruby-1.0libjruby.jar;c:opt
jruby-engine.jar;. Engines

You can perform additional testing with short programs. The following application produces a list of the available scripting engine names, language version numbers, and extensions. Note that this updated version of JRuby includes JSR-223 support in its primary JAR file; therefore, the engine does not need to be separately called out on the class path:

$ java -cp c:optjruby-9.1.6.0libjruby.jar;.
  EngineReport

import java.util.List;
import javax.script.ScriptEngineManager;
import javax.script.ScriptEngineFactory;

public class EngineReport {
  public static void main(String[] args) {
    ScriptEngineManager m =
        new ScriptEngineManager();
    List<ScriptEngineFactory> s =
        m.getEngineFactories();
    // Iterate through list of factories
    for (ScriptEngineFactory f: s) {
      // Release name and version
      String en = f.getEngineName();
      String ev = f.getEngineVersion();
      System.out.println("Engine: "
        + en + " " + ev);
      // Language name and version
      String ln = f.getLanguageName();
      String lv = f.getLanguageVersion();
      System.out.println("Language: "
        + ln + " " + lv);
      // Extensions
      List<String> l = f.getExtensions();
      for (String x: l) {
        System.out.println("Extensions: " + x);
      }
    }
  }
}

$ Engine: JSR 223 JRuby Engine 9.1.6.0
$ Language: ruby jruby 9.1.6.0
$ Extensions: rb

$ Engine: Oracle Nashorn 9-ea
$ Language: ECMAScript ECMA - 262 Edition 5.1
$ Extensions: js
Tip

Nashorn JavaScript is a scripting API packaged with Java SE 8 onwards. The command and argument jjs -scripting invokes the Nashorn engine with shell scripting fea⁠tures.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.114.221