Проблемы с оценкой Kotlin внутри JVM с помощью javax.script.ScriptEngineManager

Я пытаюсь оценить код Kotlin внутри JVM, используя API сценариев Java.

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


person NathanPB    schedule 16.12.2018    source источник


Ответы (4)


Добавление продолжения, потому что я получал ту же ошибку, но после получения зависимостей для 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.

Вот пример файла: https://github.com/JetBrains/kotlin/blob/master/libraries/examples/kotlin-jsr223-local-example/src/main/resources/META-INF/services./javax.script.ScriptEngineFactory

Этот фрагмент кода должен показать, что у вас зарегистрировано расширение kotlin.

ScriptEngineManager().engineFactories.forEach { println(it.extensions)
...
[kts]
[js]
person Chris Hinshaw    schedule 11.06.2019

Я просто исправил, добавив

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'

to my build.gradle.

PS: 1.3.11 — это моя версия Kotlin.

person NathanPB    schedule 19.12.2018
comment
Кроме того, у меня это не сработало с Maven и Kotlin версии 1.3.31. :( - person Jezor; 06.05.2019
comment
проверено, и компилятор, а не компилятор, у меня работал. Также, чтобы быть более ясным WRT расположение файла сервисов, он находится в .../‹имя_модуля›/src/main/resources/META-INF/services, где …/‹имя_модуля›/src/main/java /... возвращает вас к исходным файлам .kt - person AndrewStone; 16.05.2019

Начиная с Kotlin 1.3.31 или 1.4, в build.gradle.kts этого достаточно:

implementation(kotlin("scripting-jsr223"))
person Simon Forsberg    schedule 06.04.2021

рабочая версия в настоящее время просто:

runtimeOnly("org.jetbrains.kotlin:kotlin-scripting-jsr223:${Deps.JetBrains.Kotlin.VERSION}")

который транзитивно подключает все необходимые зависимости.

Кроме того, в этом случае файл META-INF/services/javax.script.ScriptEngineFactory кажется не нужным.

person Dirk Hoffmann    schedule 14.05.2021