【问题标题】:Can I use Kotlin Arrow-lib with Quarkus in native builds我可以在本机构建中使用 Kotlin Arrow-lib 和 Quarkus
【发布时间】:2021-03-26 17:03:31
【问题描述】:

我开始了一个新的 Kotlin 项目,我想将 arrow-kt core Lib 与 Quarkus (1.12.2) 结合使用。我想将 Quarkus 的本机编译功能与 GraalVM 一起使用。我的第一个想法是箭头是一个没有反射的简单库,但后来我读到了that。 由于 GraalVm 在运行时在本机可执行文件中存在反射问题,这会是 Arrow 的问题吗?如果这是一个问题,我可以通过简单地避开 Arrow 的某些功能来绕过这个问题吗?

我知道我可以在 Quarkus/GraalVM 中标记反射类。 反射检查哪些类?我可以简单地为几个类添加反射信息,还是我需要为整个库或我的整个代码添加反射信息?

【问题讨论】:

    标签: kotlin quarkus graalvm graalvm-native-image arrow-kt


    【解决方案1】:

    正如another answer 所说,较新的版本可能不使用反射,因此有关特定库的问题并不那么重要。不过,为了完整起见,以下是这些问题的一般答案。

    由于 GraalVm 在本机可执行文件中存在反射问题 运行时,这会是 Arrow 的问题吗?

    GraalVM 原生映像在从您的程序构建可执行文件期间使用静态分析。这意味着语言的动态特性需要显式配置以帮助分析将必要的类/方法包含到二进制文件中。例如,静态分析无法预测哪些类将通过反射访问或代理,当这些类仅通过字符串引用时,有时只能在运行时构造。

    我可以简单地为几个类添加反射信息,还是我需要为整个库或我的整个代码添加反射信息?

    您确实需要通过反射 API 配置所有访问。这些库可以为他们使用反射、资源等提供配置。但是如果他们需要对您的应用程序类进行反射访问,那么他们就不能这样做。

    所需的配置是 json 文件的形式,例如包含类的反射配置可能如下所示:

    [
      {
        "name" : "java.lang.String",
        "fields" : [
          { "name" : "value", "allowWrite" : true },
          { "name" : "hash" }
        ],
        "methods" : [
          { "name" : "<init>", "parameterTypes" : [] },
          { "name" : "<init>", "parameterTypes" : ["char[]"] },
          { "name" : "charAt" },
          { "name" : "format", "parameterTypes" : ["java.lang.String", "java.lang.Object[]"] }
        ]
      }
    ]
    

    上面的示例指定程序希望能够反射地使用java.lang.String,可以访问valuehash 字段以及列出的方法。

    创建这样的配置可能有点乏味,但相当简单。一些框架通过提供注释来标记类,然后自己生成配置来帮助您。

    但是如果你想为你不知道的库创建配置,那么手动创建配置很难,你可以使用,建议使用assisted configuration agent

    这意味着您执行启用 javaagent 的程序,它将跟踪并记下所有必要功能的配置:资源访问、序列化/反序列化、代理、JNI、反射等。

    所以你像这样运行应用程序并执行你感兴趣的代码路径(可能通过你的测试),输出目录将包含配置。

    java -agentlib:native-image-agent=config-output-dir=/path/to/config-dir/ -jar myjar.jar
    

    然后,如果需要,您可以手动编辑配置,例如,推断您未使用跟踪代理运行的代码路径。

    然后您运行传递配置选项的本机映像构建过程,例如,为反射文件配置指定: -H:ReflectionConfigurationFiles=/path/to/reflectconfig.

    您还可以使用META-INF/native-image 目录是配置文件的默认位置这一事实,因此您不必指定选项。例如,如果您在config/META-INF/native-image 目录中生成配置,那么您可以将其放在本机映像的类路径中,文件将被自动拾取:

    native-image -cp config -jar myjar.jar
    

    【讨论】:

      【解决方案2】:

      从即将发布的 0.12.0 开始,Arrow 不使用反射。以前,它在访问 ContinuationUtils 类的 bind 操作中对 MonadContinuation 的所有继承者进行 monad 理解。在这个类中,我们使用反射来读写与延续栈标签相关的私有字段。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-03-20
        • 1970-01-01
        • 1970-01-01
        • 2020-04-19
        • 2022-01-20
        • 2021-08-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多