0
# Groovy JSR-223 Scripting Engine
1
2
Groovy JSR-223 is a scripting engine implementation that provides JSR-223 (Scripting for the Java Platform) compliant support for executing Groovy scripts within Java applications. It enables seamless integration between Java and Groovy code through the standard javax.script API, supporting dynamic script execution, compiled script caching, and full integration with Groovy's language features.
3
4
## Package Information
5
6
- **Package Name**: groovy-jsr223
7
- **Package Type**: maven
8
- **Language**: Java/Groovy
9
- **Group ID**: org.codehaus.groovy
10
- **Artifact ID**: groovy-jsr223
11
- **Installation**: `<dependency><groupId>org.codehaus.groovy</groupId><artifactId>groovy-jsr223</artifactId><version>3.0.25</version></dependency>` for Maven, or `implementation 'org.codehaus.groovy:groovy-jsr223:3.0.25'` for Gradle
12
13
## Core Imports
14
15
```java
16
import javax.script.ScriptEngine;
17
import javax.script.ScriptEngineManager;
18
import javax.script.ScriptException;
19
import javax.script.Compilable;
20
import javax.script.CompiledScript;
21
import javax.script.Invocable;
22
23
// Direct factory usage
24
import org.codehaus.groovy.jsr223.GroovyScriptEngineFactory;
25
import org.codehaus.groovy.jsr223.GroovyScriptEngineImpl;
26
```
27
28
## Basic Usage
29
30
```java
31
import javax.script.ScriptEngine;
32
import javax.script.ScriptEngineManager;
33
import javax.script.ScriptException;
34
35
// Standard JSR-223 discovery
36
ScriptEngineManager manager = new ScriptEngineManager();
37
ScriptEngine engine = manager.getEngineByName("groovy");
38
39
// Execute simple script
40
try {
41
Object result = engine.eval("return 'Hello from Groovy!'");
42
System.out.println(result); // prints: Hello from Groovy!
43
44
// Set variables and execute
45
engine.put("name", "World");
46
engine.eval("greeting = 'Hello, ' + name");
47
System.out.println(engine.get("greeting")); // prints: Hello, World
48
} catch (ScriptException e) {
49
e.printStackTrace();
50
}
51
```
52
53
## Architecture
54
55
Groovy JSR-223 is built around several key components:
56
57
- **GroovyScriptEngineFactory**: Factory implementation for JSR-223 compliant engine discovery and creation, providing metadata about the Groovy scripting language and engine capabilities
58
- **GroovyScriptEngineImpl**: Main script engine implementation extending AbstractScriptEngine and implementing Compilable and Invocable interfaces, managing script compilation, execution context, and global closure state
59
- **GroovyCompiledScript**: Compiled script wrapper for improved performance with repeated executions, caching parsed script classes
60
- **Extension Classes**: ScriptExtensions and ScriptStaticExtensions providing additional Groovy-specific functionality and integration with Groovy's Binding system
61
- **Global State Management**: Uses ManagedConcurrentValueMap for caching compiled script classes and maintaining global closure references across script executions
62
- **Service Registration**: META-INF/services registration enabling automatic discovery by ScriptEngineManager
63
64
## Capabilities
65
66
### Script Engine Factory
67
68
Factory class for creating and discovering Groovy script engines through the JSR-223 API.
69
70
```java { .api }
71
/**
72
* Factory class conforming to JSR-223 for instantiating Groovy ScriptEngines
73
*/
74
public class GroovyScriptEngineFactory implements ScriptEngineFactory {
75
/**
76
* Returns the full name of the ScriptEngine
77
* @return "Groovy Scripting Engine"
78
*/
79
public String getEngineName();
80
81
/**
82
* Returns the version of the ScriptEngine
83
* @return "2.0"
84
*/
85
public String getEngineVersion();
86
87
/**
88
* Returns the name of the scripting language supported by this ScriptEngine
89
* @return "Groovy"
90
*/
91
public String getLanguageName();
92
93
/**
94
* Returns the version of the scripting language supported by this ScriptEngine
95
* @return The current Groovy runtime version
96
*/
97
public String getLanguageVersion();
98
99
/**
100
* Returns file extensions supported by this engine
101
* @return List containing "groovy"
102
*/
103
public List<String> getExtensions();
104
105
/**
106
* Returns MIME types supported by this engine
107
* @return List containing "application/x-groovy"
108
*/
109
public List<String> getMimeTypes();
110
111
/**
112
* Returns short names for the ScriptEngine
113
* @return List containing "groovy" and "Groovy"
114
*/
115
public List<String> getNames();
116
117
/**
118
* Returns the value of an attribute whose meaning may be implementation-specific
119
* @param key The name of the parameter
120
* @return The value for the given parameter
121
*/
122
public Object getParameter(String key);
123
124
/**
125
* Returns a valid scripting language executable program with given method call syntax
126
* @param obj The name representing the object whose method is to be invoked
127
* @param method The name of the method to be invoked
128
* @param args Names of the arguments in the method call
129
* @return The String used to invoke the method in the syntax of the scripting language
130
*/
131
public String getMethodCallSyntax(String obj, String method, String... args);
132
133
/**
134
* Returns a valid scripting language executable program with a given statement
135
* @param toDisplay A String to be displayed
136
* @return The string used to display the string in the syntax of the scripting language
137
*/
138
public String getOutputStatement(String toDisplay);
139
140
/**
141
* Returns a valid scripting language executable program
142
* @param statements Individual statements in the scripting language
143
* @return The Program as a String
144
*/
145
public String getProgram(String... statements);
146
147
/**
148
* Returns an instance of the ScriptEngine associated with this ScriptEngineFactory
149
* @return A new ScriptEngine instance
150
*/
151
public ScriptEngine getScriptEngine();
152
}
153
```
154
155
**Usage Example:**
156
157
```java
158
import org.codehaus.groovy.jsr223.GroovyScriptEngineFactory;
159
import javax.script.ScriptEngine;
160
161
// Direct factory usage
162
GroovyScriptEngineFactory factory = new GroovyScriptEngineFactory();
163
ScriptEngine engine = factory.getScriptEngine();
164
165
// Get factory information
166
System.out.println("Engine: " + factory.getEngineName());
167
System.out.println("Language: " + factory.getLanguageName());
168
System.out.println("Extensions: " + factory.getExtensions());
169
```
170
171
### Script Engine Implementation
172
173
Main script engine implementation providing compilation, execution, and invocation capabilities.
174
175
```java { .api }
176
/**
177
* JSR-223 Engine implementation for Groovy scripts
178
*/
179
public class GroovyScriptEngineImpl extends AbstractScriptEngine
180
implements Compilable, Invocable {
181
/**
182
* Default constructor using default GroovyClassLoader
183
*/
184
public GroovyScriptEngineImpl();
185
186
/**
187
* Constructor with custom class loader
188
* @param classLoader Custom GroovyClassLoader instance
189
*/
190
public GroovyScriptEngineImpl(GroovyClassLoader classLoader);
191
192
/**
193
* Causes the immediate execution of the script whose source is the String passed as the first argument
194
* @param script The script to be executed by the script engine
195
* @param ctx A ScriptContext exposing sets of attributes in different scopes
196
* @return The value returned from the execution of the script
197
* @throws ScriptException if an error occurs in script
198
*/
199
public Object eval(String script, ScriptContext ctx) throws ScriptException;
200
201
/**
202
* Same as eval(String, ScriptContext) where the source of the script is read from a Reader
203
* @param reader The source of the script
204
* @param ctx The ScriptContext passed to the script engine
205
* @return The return value from the script execution
206
* @throws ScriptException if an error occurs in script
207
*/
208
public Object eval(Reader reader, ScriptContext ctx) throws ScriptException;
209
210
/**
211
* Returns an uninitialized Bindings
212
* @return A Bindings that can be used to replace the state of the engine
213
*/
214
public Bindings createBindings();
215
216
/**
217
* Returns the ScriptEngineFactory for the class to which this ScriptEngine belongs
218
* @return The ScriptEngineFactory
219
*/
220
public ScriptEngineFactory getFactory();
221
222
/**
223
* Sets the class loader for this script engine
224
* @param classLoader The GroovyClassLoader to use
225
*/
226
public void setClassLoader(GroovyClassLoader classLoader);
227
228
/**
229
* Gets the class loader for this script engine
230
* @return The current GroovyClassLoader
231
*/
232
public GroovyClassLoader getClassLoader();
233
}
234
```
235
236
### Compilable Interface
237
238
Support for pre-compiling scripts to improve performance with repeated execution.
239
240
```java { .api }
241
/**
242
* Compilable interface methods for script pre-compilation
243
*/
244
public interface Compilable {
245
/**
246
* Compiles the script (source represented as a String) for later execution
247
* @param script The source of the script, represented as a String
248
* @return An instance of a subclass of CompiledScript to be executed later using eval methods
249
* @throws ScriptException if compilation fails
250
*/
251
public CompiledScript compile(String script) throws ScriptException;
252
253
/**
254
* Compiles the script (source read from Reader) for later execution
255
* @param script The reader from which the script source is obtained
256
* @return An instance of a subclass of CompiledScript to be executed later using eval methods
257
* @throws ScriptException if compilation fails
258
*/
259
public CompiledScript compile(Reader script) throws ScriptException;
260
}
261
```
262
263
**Usage Example:**
264
265
```java
266
import javax.script.Compilable;
267
import javax.script.CompiledScript;
268
import javax.script.ScriptEngine;
269
import javax.script.ScriptEngineManager;
270
271
ScriptEngineManager manager = new ScriptEngineManager();
272
ScriptEngine engine = manager.getEngineByName("groovy");
273
274
if (engine instanceof Compilable) {
275
Compilable compilable = (Compilable) engine;
276
277
// Compile script once
278
CompiledScript compiled = compilable.compile("return Math.pow(x, 2)");
279
280
// Execute multiple times with different variables
281
engine.put("x", 5);
282
Object result1 = compiled.eval(); // returns 25.0
283
284
engine.put("x", 10);
285
Object result2 = compiled.eval(); // returns 100.0
286
}
287
```
288
289
### Invocable Interface
290
291
Support for invoking functions and methods within executed scripts.
292
293
```java { .api }
294
/**
295
* Invocable interface methods for function and method invocation
296
*/
297
public interface Invocable {
298
/**
299
* Calls a method on a previously executed script
300
* @param name The name of the method to invoke
301
* @param args Arguments to pass to the method
302
* @return The return value from the method
303
* @throws ScriptException If the method does not exist or other error occurs
304
* @throws NoSuchMethodException If method with given name or matching arguments is not found
305
*/
306
public Object invokeFunction(String name, Object... args)
307
throws ScriptException, NoSuchMethodException;
308
309
/**
310
* Calls a method on an object that was set in the engine's context
311
* @param thiz Object on which the method is to be called
312
* @param name The name of the method to invoke
313
* @param args Arguments to pass to the method
314
* @return The return value from the method
315
* @throws ScriptException If the method does not exist or other error occurs
316
* @throws NoSuchMethodException If method with given name or matching arguments is not found
317
*/
318
public Object invokeMethod(Object thiz, String name, Object... args)
319
throws ScriptException, NoSuchMethodException;
320
321
/**
322
* Returns an implementation of an interface using functions compiled in the interpreter
323
* @param clazz The Class object of the interface to return
324
* @return An instance of requested interface - null if the requested interface is unavailable
325
*/
326
public <T> T getInterface(Class<T> clazz);
327
328
/**
329
* Returns an implementation of an interface using member functions of a scripting object
330
* @param thiz The scripting object whose member functions are used to implement the methods
331
* @param clazz The Class object of the interface to return
332
* @return An instance of requested interface - null if the requested interface is unavailable
333
*/
334
public <T> T getInterface(Object thiz, Class<T> clazz);
335
}
336
```
337
338
**Usage Example:**
339
340
```java
341
import javax.script.Invocable;
342
import javax.script.ScriptEngine;
343
import javax.script.ScriptEngineManager;
344
345
ScriptEngineManager manager = new ScriptEngineManager();
346
ScriptEngine engine = manager.getEngineByName("groovy");
347
348
// Define functions in script
349
engine.eval("def greet(name) { return 'Hello, ' + name }");
350
engine.eval("def add(a, b) { return a + b }");
351
352
if (engine instanceof Invocable) {
353
Invocable invocable = (Invocable) engine;
354
355
// Invoke functions
356
Object greeting = invocable.invokeFunction("greet", "Alice");
357
Object sum = invocable.invokeFunction("add", 5, 3);
358
359
System.out.println(greeting); // prints: Hello, Alice
360
System.out.println(sum); // prints: 8
361
}
362
```
363
364
### Compiled Script
365
366
Wrapper for compiled scripts enabling efficient repeated execution.
367
368
```java { .api }
369
/**
370
* Represents compiled Groovy scripts for repeated execution without reparsing
371
*/
372
public class GroovyCompiledScript extends CompiledScript {
373
/**
374
* Constructor for compiled script
375
* @param engine The script engine that compiled this script
376
* @param clazz The compiled script class
377
*/
378
public GroovyCompiledScript(GroovyScriptEngineImpl engine, Class<?> clazz);
379
380
/**
381
* Executes the program stored in this CompiledScript object
382
* @param context A ScriptContext that is used in the same way as the ScriptContext parameter passed to eval methods
383
* @return The return value from the script execution
384
* @throws ScriptException if an error occurs during script execution
385
*/
386
public Object eval(ScriptContext context) throws ScriptException;
387
388
/**
389
* Returns the ScriptEngine whose compile method created this CompiledScript
390
* @return The ScriptEngine that created this CompiledScript
391
*/
392
public ScriptEngine getEngine();
393
}
394
```
395
396
### Script Extensions
397
398
Extension methods that enhance ScriptEngine functionality with Groovy Binding integration.
399
400
```java { .api }
401
/**
402
* Extension methods for enhanced ScriptEngine functionality with Groovy Binding support
403
*/
404
public class ScriptExtensions {
405
/**
406
* Executes script with Groovy Binding integration
407
* @param self The ScriptEngine instance
408
* @param script The script source to execute
409
* @param binding A Groovy Binding containing variables for the script
410
* @return The result of script execution
411
* @throws ScriptException if error occurs in script
412
*/
413
public static Object eval(ScriptEngine self, String script, Binding binding)
414
throws ScriptException;
415
416
/**
417
* Executes script from Reader with Groovy Binding integration
418
* @param self The ScriptEngine instance
419
* @param reader The source of the script
420
* @param binding A Groovy Binding containing variables for the script
421
* @return The result of script execution
422
* @throws ScriptException if error occurs in script
423
*/
424
public static Object eval(ScriptEngine self, Reader reader, Binding binding)
425
throws ScriptException;
426
}
427
```
428
429
**Usage Example:**
430
431
```java
432
import org.codehaus.groovy.jsr223.ScriptExtensions;
433
import groovy.lang.Binding;
434
import javax.script.ScriptEngine;
435
import javax.script.ScriptEngineManager;
436
437
ScriptEngineManager manager = new ScriptEngineManager();
438
ScriptEngine engine = manager.getEngineByName("groovy");
439
440
// Create Groovy binding with variables
441
Binding binding = new Binding();
442
binding.setVariable("name", "Alice");
443
binding.setVariable("age", 30);
444
445
// Execute script with binding
446
Object result = ScriptExtensions.eval(engine,
447
"greeting = 'Hello, ' + name + '! You are ' + age + ' years old.'; return greeting",
448
binding);
449
450
System.out.println(result); // prints: Hello, Alice! You are 30 years old.
451
452
// Variables are available back in binding
453
System.out.println(binding.getVariable("greeting"));
454
```
455
456
### Script Static Extensions
457
458
Static extension methods for ScriptEngineManager providing convenient shorthand access.
459
460
```java { .api }
461
/**
462
* Static extension methods for ScriptEngineManager
463
*/
464
public class ScriptStaticExtensions {
465
/**
466
* Provides convenient shorthand for accessing a scripting engine by language name
467
* @param self Placeholder for Groovy extension method (unused)
468
* @param languageShortName The short name of the scripting engine
469
* @return The ScriptEngine corresponding to the supplied short name or null if not found
470
*/
471
public static ScriptEngine $static_propertyMissing(ScriptEngineManager self,
472
String languageShortName);
473
}
474
```
475
476
## Error Handling
477
478
The Groovy JSR-223 engine follows standard JSR-223 error handling patterns:
479
480
```java { .api }
481
/**
482
* Common exceptions thrown by the Groovy script engine
483
*/
484
public class ScriptException extends Exception {
485
// Thrown when script compilation or execution fails
486
}
487
488
public class NoSuchMethodException extends Exception {
489
// Thrown when invokeFunction or invokeMethod cannot find the specified method
490
}
491
```
492
493
**Error Handling Example:**
494
495
```java
496
import javax.script.ScriptException;
497
import javax.script.ScriptEngine;
498
import javax.script.ScriptEngineManager;
499
500
ScriptEngineManager manager = new ScriptEngineManager();
501
ScriptEngine engine = manager.getEngineByName("groovy");
502
503
try {
504
// This will cause a compilation error
505
engine.eval("invalid groovy syntax {{{");
506
} catch (ScriptException e) {
507
System.err.println("Script error: " + e.getMessage());
508
System.err.println("Line number: " + e.getLineNumber());
509
System.err.println("Column number: " + e.getColumnNumber());
510
}
511
```
512
513
## Performance Optimization
514
515
For repeated script execution, use compiled scripts:
516
517
```java
518
import javax.script.*;
519
520
ScriptEngineManager manager = new ScriptEngineManager();
521
ScriptEngine engine = manager.getEngineByName("groovy");
522
Compilable compilable = (Compilable) engine;
523
524
// Compile once
525
CompiledScript compiled = compilable.compile("return x * x + y * y");
526
527
// Execute many times with different variables
528
for (int i = 0; i < 1000; i++) {
529
engine.put("x", i);
530
engine.put("y", i + 1);
531
Object result = compiled.eval();
532
}
533
```
534
535
## Types
536
537
```java { .api }
538
// Core JSR-223 types used by Groovy engine
539
interface ScriptEngine {
540
// Standard JSR-223 interface
541
}
542
543
interface ScriptEngineFactory {
544
// Standard JSR-223 interface
545
}
546
547
interface Compilable {
548
// Standard JSR-223 interface for script compilation
549
}
550
551
interface Invocable {
552
// Standard JSR-223 interface for method invocation
553
}
554
555
abstract class CompiledScript {
556
// Standard JSR-223 abstract class for compiled scripts
557
}
558
559
interface Bindings extends Map<String, Object> {
560
// Standard JSR-223 interface for variable bindings
561
}
562
563
class ScriptContext {
564
// Standard JSR-223 class for script execution context
565
public static final int ENGINE_SCOPE = 100;
566
public static final int GLOBAL_SCOPE = 200;
567
}
568
569
// Groovy-specific types
570
class Binding {
571
// Groovy's variable binding class
572
public Object getVariable(String name);
573
public void setVariable(String name, Object value);
574
public Map<String, Object> getVariables();
575
}
576
577
class GroovyClassLoader extends ClassLoader {
578
// Groovy's specialized class loader
579
}
580
```