5

I'm trying to evaluate Kotlin code inside JVM using the 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())
}

But... ScriptEngineManager().getEngineByExtension("kts") is returning me a null value. I already added the META-INF/services file:

File Name: javax.script.ScriptEngineFactory

File Content: org.jetbrains.kotlin.script.jsr223.KotlinJsr223JvmLocalScriptEngineFactory

It sould work according to JetBrains: https://github.com/JetBrains/kotlin/tree/master/libraries/examples/kotlin-jsr223-local-example

NathanPB
  • 685
  • 1
  • 7
  • 22

4 Answers4

4

Adding a follow up because I was getting the same error but after getting the dependencies for 1.3.31 and added the script engine initialization file I was able to get it working.

My working dependencies:

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")

}

You definitely need to add the file src/main/resources/META-INF/services/javax.script.ScriptEngineFactory.

Here is the example file: https://github.com/JetBrains/kotlin/blob/master/libraries/examples/kotlin-jsr223-local-example/src/main/resources/META-INF/services/javax.script.ScriptEngineFactory

This chunk of code should show that you have the kotlin extension registered.

ScriptEngineManager().engineFactories.forEach { println(it.extensions)
...
[kts]
[js]
Chris Hinshaw
  • 6,967
  • 2
  • 39
  • 65
1

I just fixed by adding

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 is my Kotlin version.

Chris Hinshaw
  • 6,967
  • 2
  • 39
  • 65
NathanPB
  • 685
  • 1
  • 7
  • 22
  • 1
    Also, this didn't work for me with Maven and Kotlin version `1.3.31`. :( – Jezor May 06 '19 at 18:05
  • tested and compiler not compilern worked for me. Also to be more clear WRT the location of the services file, it goes in ...//src/main/resources/META-INF/services, where ...//src/main/java/... gets you to your .kt source files – AndrewStone May 16 '19 at 02:26
0

Starting around Kotlin 1.3.31 or 1.4, this seems to be enough in build.gradle.kts:

implementation(kotlin("scripting-jsr223"))
Simon Forsberg
  • 13,086
  • 10
  • 64
  • 108
0

the working version nowadays is simply:

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

which pulls in all necessary dependencies transitively.

Also the META-INF/services/javax.script.ScriptEngineFactory File seems not to be necessary if doing so.

Dirk Hoffmann
  • 1,444
  • 17
  • 35