how to use KotlinJsr223JvmLocalScriptEngineFactoryto evaluate scripts that import functions/variables from other files in the same project

Answered

Hi there,

I'm building a plugin that run Kotlin-based DSL on a server that run json scenario files with the s. The goal is to allow developers to  write tests in kotlin that genearate the json target scenario file.

Using Kotlin script files (*.custom.kts), Imanaged to arrive at a DSL that is simple enough to gain a bit of traction with our developper team, with a nice development workflow using IntelliJ. A developer can write a test like below and execute it from the IDE:

Scenario("my scenario") {
Given("my context") {
Implementation {
//...
}
}
When("get http") {
Implementation {
//...

}
}
Then("json assert") {
Implementation {
//***
}
}
}

 

I have tried to create an instance of KotlinJsr223JvmLocalScriptEngineFactory and evaluate the scripts, the flow works fine until I want to import some functions/variables from other files in the same project. my code is similar to *.main.kts.

2020-04-13 12:06:58,509 [ 183587] ERROR - plication.impl.ApplicationImpl - error: unresolved reference: Import
@file:Import("externalScript.kts")
^
error: unresolved reference:

 

 

class CustomKotlinScriptEngineFactory(val project: Project) : KotlinJsr223JvmScriptEngineFactoryBase() {
override fun getScriptEngine(): ScriptEngine {
val extractedJarLocation = CustomPluginPaths.customIdeaPluginLibPath
val jarDirectory = try {
Paths.get(extractedJarLocation)
} catch (e: FileSystemNotFoundException) {
logger.error( "Script engine creation error: can't get JAR directory for $extractedJarLocation")
throw e
}

val classpath = File(CustomPluginPaths.customIdeaPluginLibPath).listFiles()
?.filter { it.canonicalPath.endsWith(".jar") }
?.map { it }
?.toMutableList()


if (classpath != null) {
classpath += OrderEnumerator.orderEntries(project).recursively().getPathsList().pathList.map { File(it) }
}

return KotlinJsr223JvmLocalScriptEngine(
this,
classpath!!,
KotlinStandardJsr223ScriptTemplate::class.qualifiedName!!,
{ ctx, types ->
ScriptArgsWithTypes(arrayOf(ctx.getBindings(ScriptContext.ENGINE_SCOPE)), types ?: emptyArray())
},
arrayOf(Bindings::class)
)
}

companion object {
private val logger = LoggerFactory.getLogger(SpringBootKotlinScriptEngineFactory::class.java)
}
}

Any pointers would be appreciated.

2 comments
Comment actions Permalink

Hello. As this is a question about Kotlin scripting, a better place to ask would be Kotlin related sites:
* #scripting channel in Kotlin Slack: http://slack.kotlinlang.org/ (recommended for scripting questions)
* https://discuss.kotlinlang.org/

I reposted your question as an issue at https://youtrack.jetbrains.com/issue/KT-38249, please watch it for updates from the responsible developer.

0
Comment actions Permalink

Thanks for pointing me to the apporpiate channel.

0

Please sign in to leave a comment.