我可以在本机构建中将 Kotlin Arrow-lib 与 Quarkus 一起使用吗

Can I use Kotlin Arrow-lib with Quarkus in native builds

我开始了一个新的 Kotlin 项目,我想使用 arrow-kt core Lib in combination with Quarkus (1.12.2). I want to use the native compilation feature of Quarkus with the GraalVM. My first thought was that arrow is a simple lib without reflection but then i read that。 由于 GraalVm 在运行时在本机可执行文件中存在反射问题,这是否会成为 Arrow 的问题?如果这是一个问题,我可以通过简单地避免 Arrow 的某些功能来绕过这个问题吗?

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

从即将发布的0.12.0开始,Arrow不再使用反射。以前它在 monad 理解中对 MonadContinuation 的所有继承者在其 bind 操作中访问 ContinuationUtils class。在这个class中,我们使用反射来读写与continuation stack labels相关的private fields

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

Since GraalVm has a problem with reflection in native executables at runtime, will that be a problem with Arrow?

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

Can i simply add reflection information for a few classes or do i need to that for the whole lib or my whole code?

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

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

[
  {
    "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 以及列出的方法。

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

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

这意味着您执行启用 javaagent 的程序,它将跟踪并记下所有必要功能的配置:资源访问、serialization/deserialization、代理、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 目录中生成配置,那么您可以将其放在本机图像的 class 路径上,文件将自动获取:

native-image -cp config -jar myjar.jar