GraalJS ScriptEngine implementation based on JSR-223 providing JavaScript execution capabilities through the javax.script.ScriptEngine API.
—
Core JavaScript execution functionality through the JSR-223 compliant ScriptEngine interface, providing script evaluation, compilation, invocation, and variable binding capabilities with full GraalJS performance.
Execute JavaScript code from strings or readers with full error handling and context support.
/**
* Evaluates JavaScript code from a string
* @param script The JavaScript code to execute
* @return The result of the script execution
* @throws ScriptException if script execution fails
*/
Object eval(String script) throws ScriptException;
/**
* Evaluates JavaScript code from a Reader
* @param reader Reader containing JavaScript code
* @return The result of the script execution
* @throws ScriptException if script execution fails
*/
Object eval(Reader reader) throws ScriptException;
/**
* Evaluates JavaScript code with specific ScriptContext
* @param script The JavaScript code to execute
* @param context The ScriptContext to use for execution
* @return The result of the script execution
* @throws ScriptException if script execution fails
*/
Object eval(String script, ScriptContext context) throws ScriptException;
/**
* Evaluates JavaScript code from Reader with specific ScriptContext
* @param reader Reader containing JavaScript code
* @param context The ScriptContext to use for execution
* @return The result of the script execution
* @throws ScriptException if script execution fails
*/
Object eval(Reader reader, ScriptContext context) throws ScriptException;Usage Examples:
GraalJSScriptEngine engine = GraalJSScriptEngine.create();
// Simple expression evaluation
Object result = engine.eval("2 + 3 * 4");
System.out.println(result); // 14
// Multi-line script
String script = """
function fibonacci(n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
fibonacci(10);
""";
Object fibResult = engine.eval(script);
System.out.println(fibResult); // 55
// Using custom ScriptContext
SimpleScriptContext context = new SimpleScriptContext();
context.setAttribute("multiplier", 5, ScriptContext.ENGINE_SCOPE);
Object customResult = engine.eval("10 * multiplier", context);
System.out.println(customResult); // 50Compile JavaScript code for improved performance when executing the same script multiple times.
/**
* Compiles JavaScript code for repeated execution
* @param script The JavaScript code to compile
* @return CompiledScript that can be executed multiple times
* @throws ScriptException if compilation fails
*/
CompiledScript compile(String script) throws ScriptException;
/**
* Compiles JavaScript code from Reader for repeated execution
* @param reader Reader containing JavaScript code to compile
* @return CompiledScript that can be executed multiple times
* @throws ScriptException if compilation fails
*/
CompiledScript compile(Reader reader) throws ScriptException;
interface CompiledScript {
/**
* Executes the compiled script with default context
* @return The result of script execution
* @throws ScriptException if execution fails
*/
Object eval() throws ScriptException;
/**
* Executes the compiled script with specific context
* @param ctx The ScriptContext to use for execution
* @return The result of script execution
* @throws ScriptException if execution fails
*/
Object eval(ScriptContext ctx) throws ScriptException;
/**
* Returns the ScriptEngine that created this compiled script
* @return The parent ScriptEngine
*/
ScriptEngine getEngine();
}Usage Examples:
GraalJSScriptEngine engine = GraalJSScriptEngine.create();
// Compile script once
CompiledScript compiled = ((Compilable) engine).compile(
"function process(data) { return data.map(x => x * 2); } process(input);"
);
// Execute multiple times with different data
engine.put("input", Arrays.asList(1, 2, 3));
Object result1 = compiled.eval(); // [2, 4, 6]
engine.put("input", Arrays.asList(5, 10, 15));
Object result2 = compiled.eval(); // [10, 20, 30]Manage variables and objects shared between Java and JavaScript contexts.
/**
* Gets a variable value from the JavaScript global scope
* @param key The variable name
* @return The variable value or null if not found
*/
Object get(String key);
/**
* Sets a variable value in the JavaScript global scope
* @param key The variable name
* @param value The variable value
*/
void put(String key, Object value);
/**
* Gets bindings for specified scope
* @param scope ScriptContext.ENGINE_SCOPE or ScriptContext.GLOBAL_SCOPE
* @return Bindings object for the scope
*/
Bindings getBindings(int scope);
/**
* Sets bindings for specified scope
* @param bindings The bindings to set
* @param scope ScriptContext.ENGINE_SCOPE or ScriptContext.GLOBAL_SCOPE
*/
void setBindings(Bindings bindings, int scope);
/**
* Creates new empty bindings compatible with this engine
* @return New Bindings instance
*/
Bindings createBindings();Usage Examples:
GraalJSScriptEngine engine = GraalJSScriptEngine.create();
// Set Java objects in JavaScript scope
engine.put("javaList", Arrays.asList("a", "b", "c"));
engine.put("javaMap", Map.of("key", "value"));
// Access from JavaScript
engine.eval("console.log(javaList[1]);"); // "b"
engine.eval("console.log(javaMap.key);"); // "value"
// Get JavaScript variables in Java
engine.eval("var jsResult = javaList.length * 2;");
Object result = engine.get("jsResult");
System.out.println(result); // 6
// Working with custom bindings
Bindings customBindings = engine.createBindings();
customBindings.put("customVar", "Hello");
engine.setBindings(customBindings, ScriptContext.ENGINE_SCOPE);Call JavaScript functions directly from Java code with proper parameter passing and return value handling.
/**
* Invokes a top-level JavaScript function
* @param name Function name
* @param args Function arguments
* @return Function return value
* @throws ScriptException if invocation fails
* @throws NoSuchMethodException if function not found or not callable
*/
Object invokeFunction(String name, Object... args)
throws ScriptException, NoSuchMethodException;
/**
* Invokes a method on a JavaScript object
* @param thiz The JavaScript object
* @param name Method name
* @param args Method arguments
* @return Method return value
* @throws ScriptException if invocation fails
* @throws NoSuchMethodException if method not found or not callable
*/
Object invokeMethod(Object thiz, String name, Object... args)
throws ScriptException, NoSuchMethodException;Usage Examples:
GraalJSScriptEngine engine = GraalJSScriptEngine.create();
// Define JavaScript functions
engine.eval("""
function greet(name) {
return 'Hello, ' + name + '!';
}
var calculator = {
add: function(a, b) { return a + b; },
multiply: function(a, b) { return a * b; }
};
""");
// Invoke top-level function
String greeting = (String) ((Invocable) engine).invokeFunction("greet", "World");
System.out.println(greeting); // "Hello, World!"
// Invoke object method
Object calculator = engine.get("calculator");
Number sum = (Number) ((Invocable) engine).invokeMethod(calculator, "add", 5, 3);
System.out.println(sum); // 8
Number product = (Number) ((Invocable) engine).invokeMethod(calculator, "multiply", 4, 7);
System.out.println(product); // 28Create Java interface implementations backed by JavaScript objects for seamless interoperability.
/**
* Gets interface implementation from JavaScript global scope
* @param clasz The interface class to implement
* @return Implementation instance or null if interface not implementable
*/
<T> T getInterface(Class<T> clasz);
/**
* Gets interface implementation from specific JavaScript object
* @param thiz The JavaScript object to wrap
* @param clasz The interface class to implement
* @return Implementation instance or null if interface not implementable
*/
<T> T getInterface(Object thiz, Class<T> clasz);Usage Examples:
// Define Java interface
interface Calculator {
double add(double a, double b);
double subtract(double a, double b);
}
GraalJSScriptEngine engine = GraalJSScriptEngine.create();
// Implement interface in JavaScript
engine.eval("""
function add(a, b) { return a + b; }
function subtract(a, b) { return a - b; }
var calc = {
add: function(a, b) { return a + b; },
subtract: function(a, b) { return a - b; }
};
""");
// Get interface implementation from global scope
Calculator globalCalc = ((Invocable) engine).getInterface(Calculator.class);
System.out.println(globalCalc.add(10, 5)); // 15.0
// Get interface implementation from specific object
Object calc = engine.get("calc");
Calculator objCalc = ((Invocable) engine).getInterface(calc, Calculator.class);
System.out.println(objCalc.subtract(10, 5)); // 5.0Properly manage ScriptEngine resources and contexts to avoid memory leaks.
/**
* Closes the current context and makes it unusable
* Operations performed after closing will throw IllegalStateException
*/
void close();
/**
* Returns the engine factory that created this ScriptEngine
* @return GraalJSEngineFactory instance
*/
ScriptEngineFactory getFactory();Usage Examples:
// Use try-with-resources for automatic cleanup
try (GraalJSScriptEngine engine = GraalJSScriptEngine.create()) {
Object result = engine.eval("Math.PI * 2");
System.out.println(result);
// Engine automatically closed at end of try block
}
// Manual resource management
GraalJSScriptEngine engine = GraalJSScriptEngine.create();
try {
// Use engine for script execution
engine.eval("console.log('Working with engine');");
} finally {
engine.close(); // Ensure cleanup
}// Exception types thrown by ScriptEngine operations
ScriptException // Wraps JavaScript runtime errors with source location
NoSuchMethodException // Function/method not found during invocation
IllegalArgumentException // Invalid parameters
IllegalStateException // Engine closed or improperly configuredError Handling Examples:
GraalJSScriptEngine engine = GraalJSScriptEngine.create();
try {
engine.eval("nonexistentFunction()");
} catch (ScriptException e) {
System.out.println("Script error: " + e.getMessage());
System.out.println("Line number: " + e.getLineNumber());
System.out.println("File name: " + e.getFileName());
}
try {
((Invocable) engine).invokeFunction("missingFunction");
} catch (NoSuchMethodException e) {
System.out.println("Function not found: " + e.getMessage());
} catch (ScriptException e) {
System.out.println("Invocation error: " + e.getMessage());
}Install with Tessl CLI
npx tessl i tessl/maven-org-graalvm-js--js-scriptengine