What Is Scripting in Java?
Some believe that the Java Virtual Machine (JVM) can execute programs written only in the Java programming language. However, that is not true. The JVM executes language-neutral bytecode. It can execute programs written in any programming language, if the program can be compiled into Java bytecode.
A scripting language is a programming language that provides you with the ability to write scripts that are evaluated (or interpreted) by a runtime environment called a script engine (or an interpreter). A script is a sequence of characters that is written using the syntax of a scripting language and used as the source for a program executed by an interpreter. The interpreter parses the scripts, produces intermediate code, which is an internal representation of the program, and executes the intermediate code. The interpreter stores the variables used in a script in data structures called symbol tables .
Typically, unlike in a compiled programming language, the source code (called a script) in a scripting language is not compiled but is interpreted at runtime. However, scripts written in some scripting languages may be compiled into Java bytecode that can be run by the JVM.
Java 6 added scripting support to the Java platform that lets a Java application execute scripts written in scripting languages such as Rhino JavaScript, Groovy, Jython, JRuby, Nashorn JavaScript, and so on. Two-way communication is supported. It also lets scripts access Java objects created by the host application. The Java runtime and a scripting language runtime can communicate and make use of each others features.
Support for scripting languages in Java comes through the Java Scripting API. All classes and interfaces in the Java Scripting API are in the javax.script package.
Using a scripting language in a Java application provides several advantages:
Most scripting languages are dynamically typed, which makes it simpler to write programs.
They provide a quicker way to develop and test small applications.
Customization by end users is possible.
A scripting language may provide domain-specific features that are not available in Java.
Scripting languages have some disadvantages as well. For example, dynamic typing is good to write simpler code; however, it turns into a disadvantage when a type is interpreted incorrectly and you have to spend a lot of time debugging it.
Scripting support in Java lets you take advantage of both worlds: it allows you to use the Java programming language for developing statically typed, scalable, and high-performance parts of the application and use a scripting language that fits the domain-specific needs for other parts.
I will use the term script engine frequently in this book. A script engine is a software component that executes programs written in a particular scripting language. Typically, but not necessarily, a script engine is an implementation of an interpreter for a scripting language. Interpreters for several scripting languages have been implemented in Java. They expose programming interfaces so a Java program may interact with them.
JDK 7 was cobundled with a script engine called Rhino JavaScript. JDK 8 replaced the Rhino JavaScript engine with a lightweight, faster script engine called Nashorn JavaScript. This book discusses Nashorn JavaScript, not Rhino JavaScript. Please visit www.mozilla.org/rhino for more details on Rhino JavaScript documentation. If you want to migrate programs written with Rhino JavaScript to Nashorn, please visit the Rhino Migration Guide at https://wiki.openjdk.java.net/display/Nashorn/Rhino+Migration+Guide . If you are interested in using Rhino JavaScript with JDK 8, visit the page at https://wiki.openjdk.java.net/display/Nashorn/Using+Rhino+JSR-223+engine+with+JDK8 .
Java includes a command-line shell called jrunscript that can be used to run scripts in an interactive mode or a batch mode. The jrunscript shell is scripting-language-neutral; the default language is Rhino JavaScript in JDK 7 and Nashorn in JDK 8. I will discuss the jrunscript shell in detail in .
Java can execute scripts in any scripting language that provides an implementation for a script engine. For example, Java can execute scripts written in Nashorn JavaScript, Rhino JavaScript, Groovy, Jython, JRuby, and so on. Examples in this book use Nashorn JavaScript language.
In this book, the terms Nashorn, Nashorn Engine, Nashorn JavaScript, Nashorn JavaScript Engine, Nashorn Scripting Language, and JavaScript have been used synonymously.
The Nashorn scripting engine can be invoked in two ways:
In this chapter, I will discuss both ways of using the Nashorn script engine.
Executing Your First Script
In this section, you will use Nashorn to print a message on the standard output. You will access the Nashorn engine from Java code. The same steps can be used to print a message using any other scripting languages, with one difference: you will need to use the scripting language-specific code to print the message. You need to perform three steps to run a script in Java:
Create a script engine manager.
Get an instance of a script engine from the script engine manager.
Call the eval() method of the script engine to execute a script.
A script engine manager is an instance of the ScriptEngineManager class. You can create a script engine, like so:
// Create a script engine manager
ScriptEngineManager manager = new ScriptEngineManager();
An instance of the ScriptEngine interface represents a script engine in a Java program. The getEngineByName(String engineShortName) method of a ScriptEngineManager is used to get an instance of a script engine. To get an instance of the Nashorn engine, use JavaScript as the short name of the engine as shown:
// Get the reference of a Nashorn engine
ScriptEngine engine = manager.getEngineByName("JavaScript");
Tip
The short name of a script engine is case-sensitive. Sometimes a script engine has multiple short names. Nashorn engine has the following short names: nashorn , Nashorn , js , JS , JavaScript , javascript , ECMAScript , ecmascript . You can use any of the short names of an engine to get its instance using the getEngineByName() method of the ScriptEngineManager class.
In Nashorn, the print() function prints a message on the standard output and a string literal is a sequence of characters enclosed in single or double quotes. The following snippet of code stores a script in a String object that prints Hello Scripting! on the standard output:
// Store a Nashorn script in a string
String script = "print('Hello Scripting!')";
If you want to use double quotes to enclose the string literal in Nashorn, the statement will look as shown:
// Store a Nashorn script in a string
String script = "print(\"Hello Scripting!\")";