Reputation: 352
I want to load a kotlin script inside my program. I want to get the result of the script (the object returned) and use it in my kotlin code.
Here's what I have for my main method:
fun loadScript(scriptPath: String): SomeClass? {
val scriptFile = File(scriptPath)
val cl = SomeClass::class.java.classLoader
val evalConfig = ScriptCompilationConfiguration {
jvm {
this.dependenciesFromClassloader(classLoader = cl, wholeClasspath = true)
}
ide {
acceptedLocations(ScriptAcceptedLocation.Everywhere)
}
defaultImports("model.*")
}
val evalResult = BasicJvmScriptingHost().eval(
scriptFile.toScriptSource(),
evalConfig,
ScriptEvaluationConfiguration {
jvm {
baseClassLoader(cl)
}
}
)
return when (val result = evalResult) {
is ResultWithDiagnostics.Success -> {
println(SomeClass::class.java.classLoader)
println(result.value.returnValue.scriptInstance!!::class.java.classLoader)
result.value.returnValue.scriptInstance as SomeClass
}
is ResultWithDiagnostics.Failure -> {
println("Script execution failed: ${result.reports}")
null
}
}
}
fun main() {
val scriptResult = loadScript("script.kts") //?: return
println(scriptResult)
scriptResult!!.hello()
}
Here's the SomeClass code:
package model
class SomeClass {
fun hello() {
println("Hello World")
}
}
fun getSomeObject() = SomeClass()
Here's the script code:
getSomeObject()
My issue is that i keep getting the following error:
Exception in thread "main" java.lang.ClassCastException: class Script cannot be cast to class model.SomeClass (Script is in unnamed module of loader org.jetbrains.kotlin.scripting.compiler.plugin.impl.CompiledScriptClassLoader @526fc044; model.SomeClass is in unnamed module of loader 'app')
at MainKt.loadScript(Main.kt:272)
at MainKt.main(Main.kt:283)
at MainKt.main(Main.kt)
When I try to print the class loader I see i have:
jdk.internal.loader.ClassLoaders$AppClassLoader@76ed5528
for SomeClass::class.java.classLoader
and
org.jetbrains.kotlin.scripting.compiler.plugin.impl.CompiledScriptClassLoader@526fc044
for result.value.returnValue.scriptInstance!!::class.java.classLoader
Of course I understand the issue is with the class loader and that despite having the same name, the SomeClass object instanciated in the script is different than the SomeClass I try to cast into. What I don't understand is why this is happening when I specify the same class loader in the ScriptCompilationConfiguration
and ScriptEvaluationConfiguration
Upvotes: 1
Views: 38