In this example we will see how to execute a JavaScript function in Java using Nashorn. Also we will pass as an argument Java map (LinkedHashMap) which will be considered in the JavaScript as an object.
Project structure:

For this tutorial we are using Mavan with pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>NashornTest</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.openjdk.nashorn/nashorn-core -->
<dependency>
<groupId>org.openjdk.nashorn</groupId>
<artifactId>nashorn-core</artifactId>
<version>15.4</version>
</dependency>
</dependencies>
</project>As you can see we are using nashorn-core as the dependency. After Java 14 the Nashorn was removed from the JVM, so we are using it here as an external library. More information: https://github.com/openjdk/nashorn
Let’s put our JavaScript file javascript_function.js inside the folder resources:
function printProperties(obj) {
print(obj)
var total = 0;
for (var prop in obj) {
print("key: " + prop + " value: " + obj[prop]);
total = total + obj[prop];
}
return total;
}At the end we can check our only Java class:
package org.example;
import org.openjdk.nashorn.api.scripting.NashornScriptEngineFactory;
import javax.script.*;
import java.io.*;
import java.util.LinkedHashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) throws ScriptException, NoSuchMethodException, IOException {
// create a script engine manager
NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
// create a Nashorn script engine
ScriptEngine engine = factory.getScriptEngine();
// Create map that it will represent our object
Map<String, Integer> map = new LinkedHashMap<>();
map.put("Danny McCann", 200);
map.put("Hilda Ogden", 300);
map.put("Don Baldwin", 330);
/**
* Load the javascript function from the JS file.
* The content of the function:
*
* function printProperties(obj) {
* print(obj)
* var total = 0;
* for (var prop in obj) {
* print("key: " + prop + " value: " + obj[prop]);
* total = total + obj[prop];
* }
* return total;
* }
*
*/
try (InputStream is = Main.class.getClassLoader().getResourceAsStream("javascript_function.js");
Reader reader = new InputStreamReader(is)) {
engine.eval(reader);
Invocable invocable = (Invocable) engine;
/**
* Call the function passing the function name and the map as argument.
* Now the function will consider the Java Map as Javascript Object.
* It will print the key and values then it will sum up the values
*/
Object funcResult = invocable.invokeFunction("printProperties", map);
System.out.println("Class: " + funcResult.getClass() + " value: " + funcResult);
}
}
}Result:
{Danny McCann=200, Hilda Ogden=300, Don Baldwin=330}
key: Danny McCann value: 200
key: Hilda Ogden value: 300
key: Don Baldwin value: 330
Class: class java.lang.Double value: 830.0You can check the Git repository for the whole project:
