Nashorn executing JavaScript function in Java with map argument

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.0

You can check the Git repository for the whole project:

https://github.com/LevelUp8/NashornTest

Leave a Comment

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

The reCAPTCHA verification period has expired. Please reload the page.