使用 javax.script.ScriptEngineManager 在 JVM 中评估 Kotlin 的问题
Problems on evaluating Kotlin inside JVM with javax.script.ScriptEngineManager
我正在尝试使用 Java 脚本 API.
在 JVM 中评估 Kotlin 代码
try {
ScriptEngineManager().getEngineByExtension("kts").let {
it.eval("val f: (CommandContext.()->Any?) = {\n${this.args.joinToString(" ")}\n}; return f") as (CommandContext.()->Any?)
}().let { embed.setDescription(it.toString()) }
} catch (ex: Exception) {
embed.setColor(Color.RED)
embed.setDescription(StringWriter().also { ex.printStackTrace(PrintWriter(it)) }.toString())
}
但是... ScriptEngineManager().getEngineByExtension("kts")
返回了一个空值。我已经添加了 META-INF/services
文件:
文件名:javax.script.ScriptEngineFactory
文件内容:org.jetbrains.kotlin.script.jsr223.KotlinJsr223JvmLocalScriptEngineFactory
根据 JetBrains,它应该可以工作:https://github.com/JetBrains/kotlin/tree/master/libraries/examples/kotlin-jsr223-local-example
我刚刚通过添加
修复了
compile 'org.jetbrains.kotlin:kotlin-compiler:1.3.11'
compile 'org.jetbrains.kotlin:kotlin-script-runtime:1.3.11'
compile 'org.jetbrains.kotlin:kotlin-script-util:1.3.11'
compile 'org.jetbrains.kotlin:kotlin-compiler-embeddable:1.3.11'
给我的 build.gradle
.
PS: 1.3.11 是我的 Kotlin 版本。
添加跟进,因为我遇到了同样的错误,但在获取 1.3.31 的依赖项并添加脚本引擎初始化文件后,我能够让它工作。
我的工作依赖:
plugins {
base
kotlin("jvm") version "1.3.31"
}
...
dependencies {
compile(kotlin("stdlib"))
compile(kotlin("reflect"))
compile(kotlin("script-runtime"))
compile(kotlin("compiler-embeddable"))
compile(kotlin("script-util"))
runtime(kotlin("scripting-compiler-embeddable"))
testImplementation("org.junit.jupiter:junit-jupiter-api:5.2.0")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.2.0")
}
您肯定需要添加文件 src/main/resources/META-INF/services/javax.script.ScriptEngineFactory。
这段代码应该表明您已经注册了 kotlin 扩展。
ScriptEngineManager().engineFactories.forEach { println(it.extensions)
...
[kts]
[js]
从 Kotlin 1.3.31 或 1.4 开始,这在 build.gradle.kts 中似乎就足够了:
implementation(kotlin("scripting-jsr223"))
现在的工作版本很简单:
runtimeOnly("org.jetbrains.kotlin:kotlin-scripting-jsr223:${Deps.JetBrains.Kotlin.VERSION}")
这会传递所有必要的依赖项。
此外,如果这样做,META-INF/services/javax.script.ScriptEngineFactory
文件似乎不是必需的。
我正在尝试使用 Java 脚本 API.
在 JVM 中评估 Kotlin 代码try {
ScriptEngineManager().getEngineByExtension("kts").let {
it.eval("val f: (CommandContext.()->Any?) = {\n${this.args.joinToString(" ")}\n}; return f") as (CommandContext.()->Any?)
}().let { embed.setDescription(it.toString()) }
} catch (ex: Exception) {
embed.setColor(Color.RED)
embed.setDescription(StringWriter().also { ex.printStackTrace(PrintWriter(it)) }.toString())
}
但是... ScriptEngineManager().getEngineByExtension("kts")
返回了一个空值。我已经添加了 META-INF/services
文件:
文件名:javax.script.ScriptEngineFactory
文件内容:org.jetbrains.kotlin.script.jsr223.KotlinJsr223JvmLocalScriptEngineFactory
根据 JetBrains,它应该可以工作:https://github.com/JetBrains/kotlin/tree/master/libraries/examples/kotlin-jsr223-local-example
我刚刚通过添加
修复了compile 'org.jetbrains.kotlin:kotlin-compiler:1.3.11'
compile 'org.jetbrains.kotlin:kotlin-script-runtime:1.3.11'
compile 'org.jetbrains.kotlin:kotlin-script-util:1.3.11'
compile 'org.jetbrains.kotlin:kotlin-compiler-embeddable:1.3.11'
给我的 build.gradle
.
PS: 1.3.11 是我的 Kotlin 版本。
添加跟进,因为我遇到了同样的错误,但在获取 1.3.31 的依赖项并添加脚本引擎初始化文件后,我能够让它工作。
我的工作依赖:
plugins {
base
kotlin("jvm") version "1.3.31"
}
...
dependencies {
compile(kotlin("stdlib"))
compile(kotlin("reflect"))
compile(kotlin("script-runtime"))
compile(kotlin("compiler-embeddable"))
compile(kotlin("script-util"))
runtime(kotlin("scripting-compiler-embeddable"))
testImplementation("org.junit.jupiter:junit-jupiter-api:5.2.0")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.2.0")
}
您肯定需要添加文件 src/main/resources/META-INF/services/javax.script.ScriptEngineFactory。
这段代码应该表明您已经注册了 kotlin 扩展。
ScriptEngineManager().engineFactories.forEach { println(it.extensions)
...
[kts]
[js]
从 Kotlin 1.3.31 或 1.4 开始,这在 build.gradle.kts 中似乎就足够了:
implementation(kotlin("scripting-jsr223"))
现在的工作版本很简单:
runtimeOnly("org.jetbrains.kotlin:kotlin-scripting-jsr223:${Deps.JetBrains.Kotlin.VERSION}")
这会传递所有必要的依赖项。
此外,如果这样做,META-INF/services/javax.script.ScriptEngineFactory
文件似乎不是必需的。