Kotlin / Kotlin/kotlin-script-examples

Unable to switch ClassLoader if default ClassLoader is insufficient

Open
#27 0 comments 1 reaction 0 assignees View on GitHub
Dominant language
Kotlin
Stars
339
Forks
48
PR merge metrics
No merged PRs in 30d

Description

I am trying to use Kotlin Scripting inside a Quarkus Application. However the Quarkus RuntimeClassloader seems to be insufficient to load the classes into the Scripting Engine. That is basically because it only loads classes that has been indexed at startup time.

I also filed a ticket with quarkus:

https://github.com/quarkusio/quarkus/issues/43271#issuecomment-2349405532

And i created a minimal reproducer for the problem:

https://github.com/ckosmowski/kotlin-script-reproducer

1.) Start the Main class directly -> The script works. It outputs "Hello World!" and "A Model From Outside"
2.) run quarkus dev -> The output will be "Hello World" and a longish output with the message " ERROR Unresolved reference 'printName'. " at its end.

Something to add, there is a way that you can usually replace the used classloader like this:

```kotlin
val result = host.eval(StringScriptSource("""
printName()
""".trimIndent()), ScriptWithMavenDepsConfiguration, ScriptEvaluationConfiguration {
implicitReceivers(modelFromOutside)
jvm {
baseClassLoader(FilteringClassLoader(Thread.currentThread().contextClassLoader, listOf("org.example", "java.lang")))
}
})
```

FilterClassLoader:

```kotlin
class FilteringClassLoader(
parent: ClassLoader,
val allowedPackages: List
) : ClassLoader(parent) {

override fun loadClass(name: String, resolve: Boolean): Class<*> {
if (allowedPackages.any { name.startsWith(it) }) {
return super.loadClass(name, resolve)
}
throw ClassNotFoundException("Class $name is not allowed")
}
}
```

I hoped that this does the trick but however this works in the plain java version but not with quarkus dev.
Is there a way that you kotlin people could assist here, or work together with quarkus?

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with the linked minimal reproducer and compare running the Main class directly with quarkus dev. Inspect how the Kotlin Scripting API evaluates the script and how the supplied baseClassLoader interacts with the Quarkus runtime classloader. Done means the Quarkus run resolves printName and produces the same output as the direct run.

Written by the indexing model from the issue text.

Assessment

Tech stack
kotlin
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.