Проблемы при оценке Kotlin внутри JVM с помощью javax.script.ScriptEngineManager
Я пытаюсь оценить код Kotlin внутри JVM, используя Java Scripting API.
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
4 ответа
Я просто исправил, добавив
compile 'org.jetbrains.kotlin:kotlin-compilern: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
В этом случае файл кажется необязательным.