Trying to use Kotlin via javax.script (JSR 223) in a webapp


#1

Hi, I’m trying to use Kotlin (v1.2.60) packaged in a .war file deployed to WildFly (v13.0.0.Final), to be accessed through the javax.script API (JSR 223). WEB-INF/lib contains the jars from mvn packages “org.jetbrains.kotlin:kotlin-compiler-embeddable:1.2.60” and “org.jetbrains.kotlin:kotlin-script-util:1.2.60”.

Trying a simple eval like this:

ScriptEngine e = new KotlinJsr223JvmLocalScriptEngineFactory().getScriptEngine();
e.eval("1+1");

Gives this stacktrace:

java.lang.IllegalStateException: Resource not found: /kotlin/jvm/JvmStatic.class
	at deployment.kotlin_script_test.war//org.jetbrains.kotlin.script.util.impl.PathUtilKt.getResourcePathForClass(pathUtil.kt:76)
	at deployment.kotlin_script_test.war//org.jetbrains.kotlin.script.util.KotlinJars.getLib(context.kt:147)
	at deployment.kotlin_script_test.war//org.jetbrains.kotlin.script.util.KotlinJars$stdlibOrNull$2.invoke(context.kt:151)
	at deployment.kotlin_script_test.war//org.jetbrains.kotlin.script.util.KotlinJars$stdlibOrNull$2.invoke(context.kt:119)
	at deployment.kotlin_script_test.war//kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
	at deployment.kotlin_script_test.war//org.jetbrains.kotlin.script.util.KotlinJars.getStdlibOrNull(context.kt)
	at deployment.kotlin_script_test.war//org.jetbrains.kotlin.script.util.KotlinJars.getKotlinScriptStandardJars(context.kt:168)
	at deployment.kotlin_script_test.war//org.jetbrains.kotlin.script.util.ContextKt.scriptCompilationClasspathFromContextOrStlib(context.kt:109)
	at deployment.kotlin_script_test.war//org.jetbrains.kotlin.script.util.ContextKt.scriptCompilationClasspathFromContextOrStlib$default(context.kt:106)
	at deployment.kotlin_script_test.war//org.jetbrains.kotlin.script.jsr223.KotlinJsr223JvmDaemonLocalEvalScriptEngineFactory.getScriptEngine(KotlinJsr223ScriptEngineFactoryExamples.kt:46)
	at deployment.kotlin_script_test.war//kotlin.KotlinEvaluator.eval(KotlinEvaluator.java:10)

Running the code in a standalone app outside a web container with the same dependencies works fine.

Any ideas? What am I missing? Is the Kotlin script engine ready to be run inside a webapp?

Thanks, John


#2

I’ve tried to debug this and found that the method extractRoot from libraries/tools/kotlin-script-util/src/main/kotlin/org/jetbrains/kotlin/script/util/impl/pathUtil.kt is called with an URL like this:

"vfs:/PATH_TO_EXPLODED_WAR/WEB-INF/lib/kotlin-stdlib-1.2.60.jar/kotlin/jvm/JvmStatic.class"

where “vfs” seems to be a special WildFly Virtual File System protocol which the extractRoot method cannot handle because it’s hard-wired to “jar” and “file”.

Any recommendations?


#3

Seems this is an untested path. We’ll do something about it, but meanwhile, you can workaround it by specifying script compilation classpath explicitly via kotlin.compiler.classpath property. You’ll need to put at least kotlin-script-util there, and for any useful script, quite likely kotlin-stdlib as well.


#4

Thanks! I’ve added the jars to kotlin.compiler.classpath one after the other, getting various exceptions on the way. But with this classpath:

-Dkotlin.compiler.classpath=kotlin-stdlib.jar:kotlin-script-util.jar:kotlin-stdlib-common.jar:kotlin-script-runtime.jar:kotlin-compiler-embeddable.jar

I’m stuck with this:

ERROR [stderr] cannot extract: /org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment$Companion.class from vfs:/content/kotlin_script_test.war/WEB-INF/lib/kotlin-compiler-embeddable-1.2.60.jar/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment$Companion.class
ERROR [io.undertow.request] UT005023: Exception handling request to /kotlin_script_test/: java.lang.IllegalStateException: Resource not found: /org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment$Companion.class

I would be grateful if you could take this up in some future release.


#5

Hi, I am getting exactly the same errors in v1.3.10 trying to do the same in OSGi runtime (equinox). Script Engine can be created with the compiler classpath workaround, but the errors come when I try to execute a script.


#6

The kotlin script support is implemented by compiling the code at runtime and then executing the resulting code. It means you need access to the Kotlin compiler at runtime. It also means that this is not the fastest thing in the world.