Предоставление классов JVM (Kotlin), определенных с помощью скрипта JSR223

#java #kotlin #scripting #jsr223

Вопрос:

Я пытаюсь получить доступ к классу, определенному в сценарии, который оценивается с ScriptEngine помощью .

Рассмотрим следующий фрагмент:

 package com.example

interface Foo
{
    fun bar()
}

val script = """
import com.example.Foo

class MyFoo : Foo
{
    override fun bar() = println("Hello from MyFoo::bar")
}
"""

fun main()
{
    val scriptEngineManager = ScriptEngineManager()
    val scriptEngine = scriptEngineManager.getEngineByName("kotlin")
    scriptEngine.eval(script)
}
 

Это выполняется успешно, и теперь я хотел бы создать экземпляр MyFoo в коде хоста.

Единственный способ, которым мне удалось сделать это успешно, — это ScriptEngine::eval вернуть ссылку на класс, оценив выражение, ссылающееся на него:

 fun main()
{
    val scriptEngineManager = ScriptEngineManager()
    val scriptEngine = scriptEngineManager.getEngineByName("kotlin")
    scriptEngine.eval(script)
    
    // -- See below --
    val fooKClass = scriptEngine.eval("MyFoo::class") as KClass<Foo>
    val foo = fooKClass.createInstance()
    foo.bar()
}
 

Это тоже успешно выполняется, пишется Hello from MyFoo::bar в стандартном режиме.

Тем не менее, нет ли способа добавить класс, определенный сценарием, в defs классов MyFoo JVM хоста?

 fun main()
{
    val scriptEngineManager = ScriptEngineManager()
    val scriptEngine = scriptEngineManager.getEngineByName("kotlin")
    scriptEngine.eval(script)
    
    // -- See below --
    val fooKClass = Class.forName("MyFoo").kotlin as KClass<Foo>
    val foo = fooKClass.createInstance()
    foo.bar()
}
 

Вышесказанное предсказуемо терпит неудачу с a java.lang.ClassNotFoundException: MyFoo .

Является ли динамическая оценка и возврат (из ScriptEngine ) Class<*> KClass<*> экземпляра or единственным способом доступа к нему из JVM хоста?