How do I import Java package in script?

Here you can see how to import a Java class so that you can use the class, creates an instance of it in the scripting environment. We want to print out the current date on the console. For this we need to import the Date class that’s packaged under the java.util package.

In the script we can import the java.util package using the following script let Date = Java.type("java.util.Date").

package org.kodejava.script;

import javax.script.Bindings;
import javax.script.ScriptContext;
import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
import java.util.function.Predicate;

public class ImportPackageExample {
    public static void main(String[] args) {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByExtension("js");
        Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
        bindings.put("polyglot.js.allowHostAccess", true);
        bindings.put("polyglot.js.allowHostClassLookup", (Predicate<String>) s -> true);

        try {
            engine.eval(getScript());
        } catch (ScriptException e) {
            e.printStackTrace();
        }
    }

    private static String getScript() {
        return """                               
                let Date = Java.type("java.util.Date");
                let today = new Date();
                print(`Today is ${today.toString()}`);
                print(`today is ${today.getClass().getName()}`);
                """;
    }
}

This program prints the following line:

Today is Sun Oct 10 15:15:13 CST 2021
today is java.util.Date

Maven Dependencies

<dependencies>
    <dependency>
        <groupId>org.graalvm.js</groupId>
        <artifactId>js</artifactId>
        <version>22.3.2</version>
    </dependency>
    <dependency>
        <groupId>org.graalvm.js</groupId>
        <artifactId>js-scriptengine</artifactId>
        <version>22.3.2</version>
    </dependency>
</dependencies>

Maven Central Maven Central

How do I modify Java object in script?

This example show how to modify Java object from scripting environment. Below we manipulate a collection of string data. To pass data into the scripting engine we use a key-value binding to the script engine.

package org.kodejava.script;

import javax.script.Bindings;
import javax.script.ScriptContext;
import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
import java.util.List;
import java.util.ArrayList;

public class ModifiedJavaObjectFromScript {
    public static void main(String[] args) {
        // Creating an array of five colors
        List<String> colors = new ArrayList<>();
        colors.add("White");
        colors.add("Black");
        colors.add("Red");
        colors.add("Green");
        colors.add("Blue");

        // Obtain a ScriptEngine instance.
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByExtension("js");
        Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
        bindings.put("polyglot.js.allowHostAccess", true);

        // Place the colors list into the engine using colorList key.
        // After passing the list into the engine our script will be
        // able to read it.
        engine.put("colorList", colors);

        try {
            engine.eval(getScript());

            // Redisplay the modified version of colors.
            for (String color : colors) {
                System.out.println("In Java: " + color);
            }
        } catch (ScriptException e) {
            e.printStackTrace();
        }
    }

    private static String getScript() {
        // Below is our script to read the values of Java List that
        // contains string of colors. We also add some other colors
        // to the list object in the script environment.
        return """
                let index;
                let colors = colorList.toArray();

                for (index in colors) {
                    print(`In script: ${colors[index]}`);
                }

                colorList.add("Yellow");
                colorList.add("Purple");
                colorList.add("Orange");
                """;
    }
}

The output of the code snippet above is:

In script: White
In script: Black
In script: Red
In script: Green
In script: Blue
In Java: White
In Java: Black
In Java: Red
In Java: Green
In Java: Blue
In Java: Yellow
In Java: Purple
In Java: Orange

Maven Dependencies

<dependencies>
    <dependency>
        <groupId>org.graalvm.js</groupId>
        <artifactId>js</artifactId>
        <version>22.3.2</version>
    </dependency>
    <dependency>
        <groupId>org.graalvm.js</groupId>
        <artifactId>js-scriptengine</artifactId>
        <version>22.3.2</version>
    </dependency>
</dependencies>

Maven Central Maven Central

How do I access Java object from a script?

This example demonstrate how you can access Java object from a script. We start by creating the ScriptEngine object. Then we obtain the Bindings object from the engine and set the polyglot.js.allowHostAccess options to true. We do this using the Bindings‘s put(String name, Object value) method.

After that we can put Java object into the script engine by calling the ScriptEngine‘s put(String key, Object value) method. This value can later be read or access by our script. For example, we pass an array of string and a date object for our script to display.

package org.kodejava.script;

import javax.script.Bindings;
import javax.script.ScriptContext;
import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
import java.util.Date;
import java.util.function.Predicate;

public class AccessJavaObjectFromScript {
    public static void main(String[] args) {
        // Creating an array of five colors
        String[] colors = {"White", "Black", "Red", "Green", "Blue"};
        Date now = new Date();

        // Below is our script to read the values of Java array that
        // contains string of colors and also read the date object.
        String script = """
                let index;
                let colors = colorArray;

                for (index in colors) {
                    print(colors[index]);
                }

                print('----------');
                print('Today is ' + date.toString());
                """;

        // Obtain a ScriptEngine instance.
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByExtension("js");
        Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
        bindings.put("polyglot.js.allowHostAccess", true);
        bindings.put("polyglot.js.allowHostClassLookup", (Predicate<String>) s -> true);

        // Place the colors array into the engine using colorArray key. And
        // the date object using the date key.
        engine.put("colorArray", colors);
        engine.put("date", now);

        try {
            engine.eval(script);
            engine.eval("print(date instanceof Java.type('java.util.Date'))");
        } catch (ScriptException e) {
            e.printStackTrace();
        }
    }
}

Our code will print as follows:

White
Black
Red
Green
Blue
----------
Today is Sun Oct 10 09:32:06 CST 2021
true

Maven Dependencies

<dependencies>
    <dependency>
        <groupId>org.graalvm.js</groupId>
        <artifactId>js</artifactId>
        <version>22.3.2</version>
    </dependency>
    <dependency>
        <groupId>org.graalvm.js</groupId>
        <artifactId>js-scriptengine</artifactId>
        <version>22.3.2</version>
    </dependency>
</dependencies>

Maven Central Maven Central

How do I get a ScriptEngine by language name and version?

This example show you how you can obtain a script engine for a specific language name and specific language version. In the code below we try to obtain script engine instance for ECMAScript version ECMAScript 262 Edition 11.

package org.kodejava.script;

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

public class ScriptEngineSearch {
    public static void main(String[] args) {
        String languageName = "ECMAScript";
        String languageVersion = "ECMAScript 262 Edition 11";

        // Creating a ScriptEngineManager and get the list of available
        // engine factories.
        ScriptEngineManager manager = new ScriptEngineManager();
        List<ScriptEngineFactory> factories = manager.getEngineFactories();

        // We obtain a ScriptEngine from the available factories where
        // the language name is "ECMAScript" and the version is
        // "ECMAScript 262 Edition 11". ECMAScript is the standard name
        // for JavaScript programming language.
        //
        // If we found the desired language we then get the ScriptEngine
        // by calling factory's getScriptEngine() method.
        ScriptEngine engine = null;
        for (ScriptEngineFactory factory : factories) {
            String language = factory.getLanguageName();
            String version = factory.getLanguageVersion();

            if (language.equals(languageName)
                    && version.equals(languageVersion)) {
                engine = factory.getScriptEngine();
                break;
            }
        }

        if (engine != null) {
            try {
                engine.eval("print('Hello There')");
            } catch (ScriptException e) {
                e.printStackTrace();
            }
        }
    }
}

Maven Dependencies

<dependencies>
    <dependency>
        <groupId>org.graalvm.js</groupId>
        <artifactId>js</artifactId>
        <version>22.3.2</version>
    </dependency>
    <dependency>
        <groupId>org.graalvm.js</groupId>
        <artifactId>js-scriptengine</artifactId>
        <version>22.3.2</version>
    </dependency>
</dependencies>

Maven Central Maven Central

How do I call a specific function of a script?

This code demonstrate the use of Invocable interface to invoke a specific function of a script. The Invocable.invokeFunction() takes the function name with or without a parameter as the function’s parameter. The parameter value can be passed as a varargs.

package org.kodejava.script;

import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
import javax.script.Invocable;

public class InvokingFunction {
    public static void main(String[] args) {
        String script = """
                function sayHello() {
                   sayHello(null);
                }

                function sayHello(name) {
                   print('Hi there' + ((name == null) ? '!' : ' ' + name + '!'));
                }
                """;

        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByExtension("js");

        try {
            engine.eval(script);

            // Convert / cast the engine into invocable engine.
            Invocable invocableEngine = (Invocable) engine;

            // Invoking sayHello function without parameter.
            invocableEngine.invokeFunction("sayHello");

            // Invoking sayHello function with a parameter.
            invocableEngine.invokeFunction("sayHello", "Jude");
        } catch (ScriptException | NoSuchMethodException e) {
            e.printStackTrace();
        }
    }
}

This will output:

Hi there!
Hi there Jude!

Maven Dependencies

<dependencies>
    <dependency>
        <groupId>org.graalvm.js</groupId>
        <artifactId>js</artifactId>
        <version>22.3.2</version>
    </dependency>
    <dependency>
        <groupId>org.graalvm.js</groupId>
        <artifactId>js-scriptengine</artifactId>
        <version>22.3.2</version>
    </dependency>
</dependencies>

Maven Central Maven Central