0
# Script Engine Core
1
2
Core JavaScript execution functionality through the JSR-223 compliant ScriptEngine interface, providing script evaluation, compilation, invocation, and variable binding capabilities with full GraalJS performance.
3
4
## Capabilities
5
6
### Script Evaluation
7
8
Execute JavaScript code from strings or readers with full error handling and context support.
9
10
```java { .api }
11
/**
12
* Evaluates JavaScript code from a string
13
* @param script The JavaScript code to execute
14
* @return The result of the script execution
15
* @throws ScriptException if script execution fails
16
*/
17
Object eval(String script) throws ScriptException;
18
19
/**
20
* Evaluates JavaScript code from a Reader
21
* @param reader Reader containing JavaScript code
22
* @return The result of the script execution
23
* @throws ScriptException if script execution fails
24
*/
25
Object eval(Reader reader) throws ScriptException;
26
27
/**
28
* Evaluates JavaScript code with specific ScriptContext
29
* @param script The JavaScript code to execute
30
* @param context The ScriptContext to use for execution
31
* @return The result of the script execution
32
* @throws ScriptException if script execution fails
33
*/
34
Object eval(String script, ScriptContext context) throws ScriptException;
35
36
/**
37
* Evaluates JavaScript code from Reader with specific ScriptContext
38
* @param reader Reader containing JavaScript code
39
* @param context The ScriptContext to use for execution
40
* @return The result of the script execution
41
* @throws ScriptException if script execution fails
42
*/
43
Object eval(Reader reader, ScriptContext context) throws ScriptException;
44
```
45
46
**Usage Examples:**
47
48
```java
49
GraalJSScriptEngine engine = GraalJSScriptEngine.create();
50
51
// Simple expression evaluation
52
Object result = engine.eval("2 + 3 * 4");
53
System.out.println(result); // 14
54
55
// Multi-line script
56
String script = """
57
function fibonacci(n) {
58
if (n <= 1) return n;
59
return fibonacci(n - 1) + fibonacci(n - 2);
60
}
61
fibonacci(10);
62
""";
63
Object fibResult = engine.eval(script);
64
System.out.println(fibResult); // 55
65
66
// Using custom ScriptContext
67
SimpleScriptContext context = new SimpleScriptContext();
68
context.setAttribute("multiplier", 5, ScriptContext.ENGINE_SCOPE);
69
Object customResult = engine.eval("10 * multiplier", context);
70
System.out.println(customResult); // 50
71
```
72
73
### Script Compilation
74
75
Compile JavaScript code for improved performance when executing the same script multiple times.
76
77
```java { .api }
78
/**
79
* Compiles JavaScript code for repeated execution
80
* @param script The JavaScript code to compile
81
* @return CompiledScript that can be executed multiple times
82
* @throws ScriptException if compilation fails
83
*/
84
CompiledScript compile(String script) throws ScriptException;
85
86
/**
87
* Compiles JavaScript code from Reader for repeated execution
88
* @param reader Reader containing JavaScript code to compile
89
* @return CompiledScript that can be executed multiple times
90
* @throws ScriptException if compilation fails
91
*/
92
CompiledScript compile(Reader reader) throws ScriptException;
93
94
interface CompiledScript {
95
/**
96
* Executes the compiled script with default context
97
* @return The result of script execution
98
* @throws ScriptException if execution fails
99
*/
100
Object eval() throws ScriptException;
101
102
/**
103
* Executes the compiled script with specific context
104
* @param ctx The ScriptContext to use for execution
105
* @return The result of script execution
106
* @throws ScriptException if execution fails
107
*/
108
Object eval(ScriptContext ctx) throws ScriptException;
109
110
/**
111
* Returns the ScriptEngine that created this compiled script
112
* @return The parent ScriptEngine
113
*/
114
ScriptEngine getEngine();
115
}
116
```
117
118
**Usage Examples:**
119
120
```java
121
GraalJSScriptEngine engine = GraalJSScriptEngine.create();
122
123
// Compile script once
124
CompiledScript compiled = ((Compilable) engine).compile(
125
"function process(data) { return data.map(x => x * 2); } process(input);"
126
);
127
128
// Execute multiple times with different data
129
engine.put("input", Arrays.asList(1, 2, 3));
130
Object result1 = compiled.eval(); // [2, 4, 6]
131
132
engine.put("input", Arrays.asList(5, 10, 15));
133
Object result2 = compiled.eval(); // [10, 20, 30]
134
```
135
136
### Variable Binding
137
138
Manage variables and objects shared between Java and JavaScript contexts.
139
140
```java { .api }
141
/**
142
* Gets a variable value from the JavaScript global scope
143
* @param key The variable name
144
* @return The variable value or null if not found
145
*/
146
Object get(String key);
147
148
/**
149
* Sets a variable value in the JavaScript global scope
150
* @param key The variable name
151
* @param value The variable value
152
*/
153
void put(String key, Object value);
154
155
/**
156
* Gets bindings for specified scope
157
* @param scope ScriptContext.ENGINE_SCOPE or ScriptContext.GLOBAL_SCOPE
158
* @return Bindings object for the scope
159
*/
160
Bindings getBindings(int scope);
161
162
/**
163
* Sets bindings for specified scope
164
* @param bindings The bindings to set
165
* @param scope ScriptContext.ENGINE_SCOPE or ScriptContext.GLOBAL_SCOPE
166
*/
167
void setBindings(Bindings bindings, int scope);
168
169
/**
170
* Creates new empty bindings compatible with this engine
171
* @return New Bindings instance
172
*/
173
Bindings createBindings();
174
```
175
176
**Usage Examples:**
177
178
```java
179
GraalJSScriptEngine engine = GraalJSScriptEngine.create();
180
181
// Set Java objects in JavaScript scope
182
engine.put("javaList", Arrays.asList("a", "b", "c"));
183
engine.put("javaMap", Map.of("key", "value"));
184
185
// Access from JavaScript
186
engine.eval("console.log(javaList[1]);"); // "b"
187
engine.eval("console.log(javaMap.key);"); // "value"
188
189
// Get JavaScript variables in Java
190
engine.eval("var jsResult = javaList.length * 2;");
191
Object result = engine.get("jsResult");
192
System.out.println(result); // 6
193
194
// Working with custom bindings
195
Bindings customBindings = engine.createBindings();
196
customBindings.put("customVar", "Hello");
197
engine.setBindings(customBindings, ScriptContext.ENGINE_SCOPE);
198
```
199
200
### Function Invocation
201
202
Call JavaScript functions directly from Java code with proper parameter passing and return value handling.
203
204
```java { .api }
205
/**
206
* Invokes a top-level JavaScript function
207
* @param name Function name
208
* @param args Function arguments
209
* @return Function return value
210
* @throws ScriptException if invocation fails
211
* @throws NoSuchMethodException if function not found or not callable
212
*/
213
Object invokeFunction(String name, Object... args)
214
throws ScriptException, NoSuchMethodException;
215
216
/**
217
* Invokes a method on a JavaScript object
218
* @param thiz The JavaScript object
219
* @param name Method name
220
* @param args Method arguments
221
* @return Method return value
222
* @throws ScriptException if invocation fails
223
* @throws NoSuchMethodException if method not found or not callable
224
*/
225
Object invokeMethod(Object thiz, String name, Object... args)
226
throws ScriptException, NoSuchMethodException;
227
```
228
229
**Usage Examples:**
230
231
```java
232
GraalJSScriptEngine engine = GraalJSScriptEngine.create();
233
234
// Define JavaScript functions
235
engine.eval("""
236
function greet(name) {
237
return 'Hello, ' + name + '!';
238
}
239
240
var calculator = {
241
add: function(a, b) { return a + b; },
242
multiply: function(a, b) { return a * b; }
243
};
244
""");
245
246
// Invoke top-level function
247
String greeting = (String) ((Invocable) engine).invokeFunction("greet", "World");
248
System.out.println(greeting); // "Hello, World!"
249
250
// Invoke object method
251
Object calculator = engine.get("calculator");
252
Number sum = (Number) ((Invocable) engine).invokeMethod(calculator, "add", 5, 3);
253
System.out.println(sum); // 8
254
255
Number product = (Number) ((Invocable) engine).invokeMethod(calculator, "multiply", 4, 7);
256
System.out.println(product); // 28
257
```
258
259
### Interface Implementation
260
261
Create Java interface implementations backed by JavaScript objects for seamless interoperability.
262
263
```java { .api }
264
/**
265
* Gets interface implementation from JavaScript global scope
266
* @param clasz The interface class to implement
267
* @return Implementation instance or null if interface not implementable
268
*/
269
<T> T getInterface(Class<T> clasz);
270
271
/**
272
* Gets interface implementation from specific JavaScript object
273
* @param thiz The JavaScript object to wrap
274
* @param clasz The interface class to implement
275
* @return Implementation instance or null if interface not implementable
276
*/
277
<T> T getInterface(Object thiz, Class<T> clasz);
278
```
279
280
**Usage Examples:**
281
282
```java
283
// Define Java interface
284
interface Calculator {
285
double add(double a, double b);
286
double subtract(double a, double b);
287
}
288
289
GraalJSScriptEngine engine = GraalJSScriptEngine.create();
290
291
// Implement interface in JavaScript
292
engine.eval("""
293
function add(a, b) { return a + b; }
294
function subtract(a, b) { return a - b; }
295
296
var calc = {
297
add: function(a, b) { return a + b; },
298
subtract: function(a, b) { return a - b; }
299
};
300
""");
301
302
// Get interface implementation from global scope
303
Calculator globalCalc = ((Invocable) engine).getInterface(Calculator.class);
304
System.out.println(globalCalc.add(10, 5)); // 15.0
305
306
// Get interface implementation from specific object
307
Object calc = engine.get("calc");
308
Calculator objCalc = ((Invocable) engine).getInterface(calc, Calculator.class);
309
System.out.println(objCalc.subtract(10, 5)); // 5.0
310
```
311
312
### Resource Management
313
314
Properly manage ScriptEngine resources and contexts to avoid memory leaks.
315
316
```java { .api }
317
/**
318
* Closes the current context and makes it unusable
319
* Operations performed after closing will throw IllegalStateException
320
*/
321
void close();
322
323
/**
324
* Returns the engine factory that created this ScriptEngine
325
* @return GraalJSEngineFactory instance
326
*/
327
ScriptEngineFactory getFactory();
328
```
329
330
**Usage Examples:**
331
332
```java
333
// Use try-with-resources for automatic cleanup
334
try (GraalJSScriptEngine engine = GraalJSScriptEngine.create()) {
335
Object result = engine.eval("Math.PI * 2");
336
System.out.println(result);
337
// Engine automatically closed at end of try block
338
}
339
340
// Manual resource management
341
GraalJSScriptEngine engine = GraalJSScriptEngine.create();
342
try {
343
// Use engine for script execution
344
engine.eval("console.log('Working with engine');");
345
} finally {
346
engine.close(); // Ensure cleanup
347
}
348
```
349
350
## Error Handling
351
352
```java { .api }
353
// Exception types thrown by ScriptEngine operations
354
ScriptException // Wraps JavaScript runtime errors with source location
355
NoSuchMethodException // Function/method not found during invocation
356
IllegalArgumentException // Invalid parameters
357
IllegalStateException // Engine closed or improperly configured
358
```
359
360
**Error Handling Examples:**
361
362
```java
363
GraalJSScriptEngine engine = GraalJSScriptEngine.create();
364
365
try {
366
engine.eval("nonexistentFunction()");
367
} catch (ScriptException e) {
368
System.out.println("Script error: " + e.getMessage());
369
System.out.println("Line number: " + e.getLineNumber());
370
System.out.println("File name: " + e.getFileName());
371
}
372
373
try {
374
((Invocable) engine).invokeFunction("missingFunction");
375
} catch (NoSuchMethodException e) {
376
System.out.println("Function not found: " + e.getMessage());
377
} catch (ScriptException e) {
378
System.out.println("Invocation error: " + e.getMessage());
379
}
380
```