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 模板修改为:
- 添加
@io.quarkus.runtime.annotations.RegisterForReflection
注释
- 使用惰性初始化在构造函数中初始化静态。
- 从运行时 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>
找到基础模板
我有一个第三方 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 模板修改为:
- 添加
@io.quarkus.runtime.annotations.RegisterForReflection
注释 - 使用惰性初始化在构造函数中初始化静态。
- 从运行时 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>
找到基础模板