Quarkus 本机构建 class 在构建和 运行 时间初始化

Quarkus native build class in both build and run time initialization

我有一个第三方 class,Quarkus 添加到构建时初始化,但由于使用静态线程,它需要 运行 时间初始化。将它添加到 运行 时初始化本机构建然后抱怨它在两者中。

重现此内容的示例项目:https://github.com/hshorter/quarkus-avro-decode-example

使用“--initialize-at-运行-time=org.apache.avro.specific.SpecificDatumReader”:

Error: Classes that should be initialized at run time got initialized during image building: org.apache.avro.specific.SpecificDatumReader the class was requested to be initialized at build time (from the command line). To see why org.apache.avro.specific.SpecificDatumReader got initialized use -H:+TraceClassInitialization

没有“--initialize-at-运行-time=org.apache.avro.specific.SpecificDatumReader”:

Error: Detected a started Thread in the image heap. Threads running in the image generator are no longer running at image run time. To see how this object got instantiated use -H:+TraceClassInitialization. The object was probably created by a class initializer and is reachable from a static field. You can request class initialization at image run time by using the option --initialize-at-build-time=. Or you can write your own initialization methods and call them explicitly from your main entry point. Detailed message: Trace: object org.apache.avro.specific.SpecificDatumReader

非常感谢任何帮助。

抱歉,我来晚了,但你遇到的问题是,当你要求 SpecificDatumReader 在运行时初始化时,另一个 class 在构建时初始化需要 SpecificDatumReader 待初始化。

所以基本上,您需要做一些侦探工作来确定这个 class 被初始化的原因,并可能将 class 初始化那个也标记为运行时初始化。

请注意,有时它可能有点毛茸茸。

我们刚刚解决了这个问题,在生成的代码中有一个像这样的静态初始化器: private static BinaryMessageEncoder ENCODER = new BinaryMessageEncoder(MODEL$, SCHEMA$); private static BinaryMessageDecoder DECODER = new BinaryMessageDecoder(MODEL$, SCHEMA$);

我们将 Avro 代码生成中的 Velocity 模板修改为:

  1. 添加 @io.quarkus.runtime.annotations.RegisterForReflection 注释
  2. 使用惰性初始化在构造函数中初始化静态。
  3. 从运行时 class init 中删除那些 classes。 缺点是您必须维护自定义代码生成模板。不过这相对容易,这里是自动化代码生成的 maven 配置:
<plugin>
  <groupId>org.apache.avro</groupId>
  <artifactId>avro-maven-plugin</artifactId>
  <version>${avro.version}</version>
  <executions>
    <execution>
      <id>schemas</id>
      <phase>generate-sources</phase>
      <goals>
        <goal>schema</goal>
      </goals>
      <configuration>
 <templateDirectory>${project.basedir}/src/main/resources/avro/templates/</templateDirectory>
      </configuration>
    </execution>
  </executions>
</plugin>

您可以在 https://github.com/apache/avro/tree/master/lang/java/compiler/src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic

找到基础模板