0
# JSR-223 Script Engines
1
2
The kotlin-script-util library provides two JSR-223 compliant script engine implementations for executing Kotlin code within Java applications. Both engines allow dynamic compilation and execution of Kotlin scripts with different performance characteristics.
3
4
## Script Engine Factories
5
6
### KotlinJsr223JvmScriptEngineFactoryBase
7
8
Base factory class that provides common functionality for all Kotlin JSR-223 script engine factories.
9
10
```kotlin { .api }
11
abstract class KotlinJsr223JvmScriptEngineFactoryBase : ScriptEngineFactory {
12
abstract fun getScriptEngine(): ScriptEngine
13
14
// ScriptEngineFactory implementation
15
fun getEngineName(): String = "kotlin"
16
fun getEngineVersion(): String
17
fun getExtensions(): List<String> = listOf("kts")
18
fun getLanguageName(): String = "kotlin"
19
fun getLanguageVersion(): String
20
fun getMimeTypes(): List<String> = listOf("text/x-kotlin")
21
fun getNames(): List<String> = listOf("kotlin")
22
fun getParameter(key: String): Any?
23
fun getMethodCallSyntax(obj: String, m: String, vararg args: String): String
24
fun getOutputStatement(toDisplay: String): String
25
fun getProgram(vararg statements: String): String
26
}
27
```
28
29
### KotlinJsr223JvmLocalScriptEngineFactory
30
31
Factory that creates script engines using local compilation.
32
33
```kotlin { .api }
34
class KotlinJsr223JvmLocalScriptEngineFactory : KotlinJsr223JvmScriptEngineFactoryBase {
35
fun getScriptEngine(): ScriptEngine
36
}
37
```
38
39
**Usage Example:**
40
41
```kotlin
42
import org.jetbrains.kotlin.script.jsr223.KotlinJsr223JvmLocalScriptEngineFactory
43
44
val factory = KotlinJsr223JvmLocalScriptEngineFactory()
45
val engine = factory.scriptEngine
46
47
// Execute simple expressions
48
val result = engine.eval("println(\"Hello from Kotlin script!\")")
49
```
50
51
### KotlinJsr223JvmDaemonLocalEvalScriptEngineFactory
52
53
Factory that creates script engines using daemon-based compilation for better performance with repeated script execution.
54
55
```kotlin { .api }
56
class KotlinJsr223JvmDaemonLocalEvalScriptEngineFactory : KotlinJsr223JvmScriptEngineFactoryBase {
57
fun getScriptEngine(): ScriptEngine
58
}
59
```
60
61
**Usage Example:**
62
63
```kotlin
64
import org.jetbrains.kotlin.script.jsr223.KotlinJsr223JvmDaemonLocalEvalScriptEngineFactory
65
66
val factory = KotlinJsr223JvmDaemonLocalEvalScriptEngineFactory()
67
val engine = factory.scriptEngine
68
69
// Better for repeated script execution
70
for (i in 1..10) {
71
val result = engine.eval("Math.pow($i.toDouble(), 2.0)")
72
println("$i squared = $result")
73
}
74
```
75
76
## Script Engine Implementations
77
78
### KotlinJsr223JvmLocalScriptEngine
79
80
Script engine implementation using local compilation.
81
82
```kotlin { .api }
83
class KotlinJsr223JvmLocalScriptEngine(
84
factory: ScriptEngineFactory,
85
val templateClasspath: List<File>,
86
templateClassName: String,
87
val getScriptArgs: (ScriptContext, Array<out KClass<out Any>>?) -> ScriptArgsWithTypes?,
88
val scriptArgsTypes: Array<out KClass<out Any>>?
89
) : KotlinJsr223JvmScriptEngineBase(factory), KotlinJsr223JvmInvocableScriptEngine {
90
91
val replCompiler: ReplCompiler
92
val replEvaluator: ReplFullEvaluator
93
val state: IReplStageState<*>
94
95
fun createState(lock: ReentrantReadWriteLock): IReplStageState<*>
96
fun overrideScriptArgs(context: ScriptContext): ScriptArgsWithTypes?
97
}
98
```
99
100
### KotlinJsr223JvmDaemonCompileScriptEngine
101
102
Script engine implementation using daemon-based compilation for improved performance.
103
104
```kotlin { .api }
105
class KotlinJsr223JvmDaemonCompileScriptEngine(
106
factory: ScriptEngineFactory,
107
compilerClasspath: List<File>,
108
templateClasspath: List<File>,
109
templateClassName: String,
110
val getScriptArgs: (ScriptContext, Array<out KClass<out Any>>?) -> ScriptArgsWithTypes?,
111
val scriptArgsTypes: Array<out KClass<out Any>>?,
112
compilerOut: OutputStream = System.err
113
) : KotlinJsr223JvmScriptEngineBase(factory), KotlinJsr223JvmInvocableScriptEngine {
114
115
val replCompiler: ReplCompilerWithoutCheck
116
val localEvaluator: GenericReplCompilingEvaluator
117
val replEvaluator: ReplFullEvaluator
118
val state: IReplStageState<*>
119
120
fun createState(lock: ReentrantReadWriteLock): IReplStageState<*>
121
fun overrideScriptArgs(context: ScriptContext): ScriptArgsWithTypes?
122
}
123
```
124
125
## Working with Bindings
126
127
Both script engines support passing data to scripts through bindings:
128
129
```kotlin
130
import org.jetbrains.kotlin.script.jsr223.KotlinJsr223JvmLocalScriptEngineFactory
131
132
val engine = KotlinJsr223JvmLocalScriptEngineFactory().scriptEngine
133
134
// Create bindings and add variables
135
val bindings = engine.createBindings()
136
bindings["name"] = "World"
137
bindings["count"] = 42
138
139
// Execute script with bindings
140
val result = engine.eval("""
141
println("Hello, ${"$"}name!")
142
count * 2
143
""".trimIndent(), bindings)
144
145
println("Result: $result") // Result: 84
146
```
147
148
## Error Handling
149
150
Script engines throw `ScriptException` for compilation and runtime errors:
151
152
```kotlin
153
import javax.script.ScriptException
154
155
val engine = KotlinJsr223JvmLocalScriptEngineFactory().scriptEngine
156
157
try {
158
engine.eval("invalid syntax @@#")
159
} catch (e: ScriptException) {
160
println("Script compilation failed: ${e.message}")
161
}
162
163
try {
164
engine.eval("throw RuntimeException(\"Script error\")")
165
} catch (e: ScriptException) {
166
println("Script execution failed: ${e.message}")
167
}
168
```
169
170
## Types
171
172
```kotlin { .api }
173
// Base interface for invocable script engines
174
interface KotlinJsr223JvmInvocableScriptEngine {
175
val replEvaluator: ReplFullEvaluator
176
val state: IReplStageState<*>
177
fun createState(lock: ReentrantReadWriteLock): IReplStageState<*>
178
fun overrideScriptArgs(context: ScriptContext): ScriptArgsWithTypes?
179
}
180
181
// Base class for all Kotlin JSR-223 script engines
182
abstract class KotlinJsr223JvmScriptEngineBase(
183
factory: ScriptEngineFactory
184
) : AbstractScriptEngine(factory.context) {
185
fun eval(script: String): Any?
186
fun eval(script: String, context: ScriptContext): Any?
187
fun eval(reader: Reader): Any?
188
fun eval(reader: Reader, context: ScriptContext): Any?
189
fun createBindings(): Bindings
190
fun getFactory(): ScriptEngineFactory
191
}
192
193
// Script arguments with type information
194
data class ScriptArgsWithTypes(
195
val scriptArgs: Array<out Any?>,
196
val scriptArgsTypes: Array<out KClass<out Any>>
197
)
198
199
// Standard Java/Kotlin types used by script engines
200
typealias ReentrantReadWriteLock = java.util.concurrent.locks.ReentrantReadWriteLock
201
typealias OutputStream = java.io.OutputStream
202
```