【问题标题】:Kotlin dynamically compile a class from source code at runtimeKotlin 在运行时从源代码动态编译类
【发布时间】:2018-03-21 20:54:04
【问题描述】:

是否可以在运行时编译和实例化 Kotlin 类?我说的是类似的东西,但使用的是 Kotlin API:How do I programmatically compile and instantiate a Java class?

例如: 我将完整的类定义为字符串:

val example = "package example\n" +
        "\n" +
        "fun main(args: Array<String>) {\n" +
        "    println(\"Hello World\")\n" +
        "}\n"

然后将它插入到一些 class.kt 中并运行它,这样我就可以在运行时在控制台中打印“Hello World”。

【问题讨论】:

标签: kotlin


【解决方案1】:

您可能想查看 Kotlin 脚本,请参阅 https://github.com/andrewoma/kotlin-script

或者,您需要编写自己的 eval(kotlin-code-string-here) 方法,该方法将转储 blah.kt 文件中的文本,例如,使用外部 Kotlin 编译器将其编译为 blah.class,然后使用动态将这些类加载到运行时Java 类加载器做这样的事情:

MainClass.class.classLoader.loadClass("com.mypackage.MyClass")

这可能非常缓慢且不可靠。

另一个不太好的选择是使用 Rhino 并在您的 Kotlin 代码中运行 JavaScript。所以再一次,你将有一个 eval(kotlin-code-string-here) 方法将内容转储到 blah.kt 文件,然后你将使用 Kotlin2JS 编译器将其编译为 JavaScript 并使用 Rhino 直接在 Kotlin 中执行 JavaScript,这不是很好要么。

另一种选择是使用 Kotlin 脚本或外部 Kotlin 编译器(在这两种情况下,Kotlin 编译器都必须启动),并且这样做也可以让您动态执行,尽管只能在 Unix 系统上执行.

Runtime.getRuntime().exec("""  "kotlin code here" > blah.kts | sh""")

我不知道有一个干净的解决方案,Kotlin 的设计不是像 PHP / JavaScript / Python 那样运行,它只是动态解释文本,它必须先编译成字节码,然后才能在 JVM 上做任何事情;因此,在每种情况下,您都需要先以一种或另一种方式编译该代码,无论是字节码还是 javascript,并且在这两种情况下都使用 Java 类加载器或 Rhino 将其加载到您的应用程序中。

【讨论】:

  • 呃。分叉 Kotlin 编译器不算作动态评估。
【解决方案2】:

请检查this solution 的依赖项、jar 资源等。以下代码不足以成功执行。

但是,要编译动态类,您可以执行以下操作:

val classLoader = Thread.currentThread().contextClassLoader

val engineManager = ScriptEngineManager(classLoader)

setIdeaIoUseFallback() // hack to have ability to do this from IntelliJ Idea context

val ktsEngine: ScriptEngine = engineManager.getEngineByExtension("kts")

ktsEngine.eval("object MyClass { val number = 123 } ")

println(ktsEngine.eval("MyClass.number"))

请注意:这里可能存在代码注入。请小心并为此使用专用进程或专用 ClassLoader。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-16
    • 1970-01-01
    • 2017-12-16
    • 2016-04-15
    • 2019-11-17
    • 1970-01-01
    相关资源
    最近更新 更多