Published: Novembar 3, 2016
Introduction
Java provides an excellent feature for integrating JavaScript into Java applications through the Nashorn JavaScript Engine. Introduced in Java 8, Nashorn allows you to execute JavaScript code from within a Java application with high performance and efficiency.
In this tutorial, we will explore:
- What Nashorn is and how it works.
- How to run JavaScript code from Java.
- Practical examples of using Nashorn to integrate JavaScript in Java applications.
By the end of this tutorial, you’ll be able to harness the power of Nashorn to run JavaScript directly from Java, which is useful for extending Java applications with scripting capabilities.
What is Nashorn?
Nashorn is a JavaScript runtime built into the Java Virtual Machine (JVM). It provides a high-performance engine for executing JavaScript code in Java applications. Nashorn is a replacement for the older Rhino JavaScript engine and offers improved performance, supporting the latest ECMAScript standards.
Some key features of Nashorn:
- It executes JavaScript code directly within Java.
- It provides access to Java classes and Java objects from JavaScript code.
- It supports both JavaScript syntax and the Java API, making it easy to interact with Java from JavaScript and vice versa.
Setting Up Nashorn
Nashorn is available by default in JDK 8 and later versions, so you don’t need to install anything extra. However, it’s important to note that Nashorn has been deprecated as of JDK 11, so for modern Java versions, alternatives like GraalVM are recommended for running JavaScript.
To use Nashorn, you simply need to invoke it through the Java Scripting API (javax.script) provided by the Java platform.
Running JavaScript from Java
Example 1: Running a Simple JavaScript Expression
Let’s start by running a simple JavaScript expression from Java using Nashorn:
import javax.script.*;
public class NashornExample {
public static void main(String[] args) {
try {
// Create a script engine
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
// Define a simple JavaScript code
String script = "var x = 5; var y = 10; x + y;";
// Execute the script
Object result = engine.eval(script);
// Print the result
System.out.println("Result of JavaScript evaluation: " + result); // Output: 15
} catch (ScriptException e) {
e.printStackTrace();
}
}
}
In this example:
- We create a
ScriptEngine
instance that uses Nashorn. - We define a JavaScript expression that adds two numbers.
- We execute the script with
engine.eval()
and print the result.
Example 2: Using JavaScript Functions in Java
Nashorn allows you to define and call JavaScript functions from Java. Let’s define a JavaScript function and call it from Java:
import javax.script.*;
public class NashornExample {
public static void main(String[] args) {
try {
// Create a script engine
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
// Define a JavaScript function
String script = "function greet(name) { return 'Hello, ' + name; }";
// Evaluate the script to define the function
engine.eval(script);
// Call the function from Java
Invocable invocable = (Invocable) engine;
Object result = invocable.invokeFunction("greet", "Java Developer");
// Print the result
System.out.println(result); // Output: Hello, Java Developer
} catch (ScriptException | NoSuchMethodException e) {
e.printStackTrace();
}
}
}
Here:
- We define a JavaScript function
greet()
that takes aname
as an argument and returns a greeting. - We then call this function from Java using the
Invocable
interface, passing in"Java Developer"
as an argument.
Accessing Java Objects from JavaScript
One of the powerful features of Nashorn is the ability to interact with Java objects from JavaScript. This allows you to use Java classes and libraries directly in your JavaScript code.
Example 3: Using Java Classes in JavaScript
Let’s access Java classes (like ArrayList
) and use them in JavaScript:
import javax.script.*;
import java.util.ArrayList;
public class NashornExample {
public static void main(String[] args) {
try {
// Create a script engine
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
// Define Java objects in JavaScript
String script = "var list = new java.util.ArrayList();"
+ "list.add('Java');"
+ "list.add('JavaScript');"
+ "list.add('Nashorn');"
+ "list;";
// Evaluate the script
Object result = engine.eval(script);
// Print the result (Java List)
System.out.println("List from JavaScript: " + result); // Output: [Java, JavaScript, Nashorn]
} catch (ScriptException e) {
e.printStackTrace();
}
}
}
In this example:
- We create a Java
ArrayList
from JavaScript usingnew java.util.ArrayList()
. - We add elements to the list and return it.
- The list is printed as a Java
ArrayList
object.
Handling JavaScript Exceptions in Java
You can handle exceptions in JavaScript just like you would in Java. Nashorn allows you to catch and throw exceptions between Java and JavaScript seamlessly.
Example 4: Handling Errors
import javax.script.*;
public class NashornExample {
public static void main(String[] args) {
try {
// Create a script engine
ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn");
// Define a JavaScript function that throws an exception
String script = "function throwError() { throw new Error('Something went wrong!'); }";
// Evaluate the script
engine.eval(script);
// Call the function that throws an error
Invocable invocable = (Invocable) engine;
invocable.invokeFunction("throwError");
} catch (ScriptException | NoSuchMethodException e) {
System.out.println("Caught JavaScript exception: " + e.getMessage());
}
}
}
In this example:
- We define a JavaScript function
throwError()
that throws an exception. - When the function is invoked, the exception is caught and printed by the Java
catch
block.
Conclusion
The Nashorn JavaScript engine makes it easy to run JavaScript code from Java applications, bridging the gap between Java and JavaScript. This functionality is useful for scenarios like adding scripting capabilities to your Java application or integrating with JavaScript libraries.
However, with the deprecation of Nashorn in JDK 11 and its removal in JDK 15, you may want to consider other alternatives like GraalVM if you’re working with modern Java versions.
In the next tutorial, we will explore the flatMap() method in Java 8’s Streams API and its usage in handling more complex data structures.