0

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

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

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

错误:应该在运行时初始化的类在图像构建期间被初始化:org.apache.avro.specific.SpecificDatumReader 请求在构建时初始化类(从命令行)。要查看 org.apache.avro.specific.SpecificDatumReader 被初始化的原因,请使用 -H:+TraceClassInitialization

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

错误:在图像堆中检测到一个已启动的线程。在图像生成器中运行的线程不再在图像运行时运行。要查看这个对象是如何被实例化的,请使用 -H:+TraceClassInitialization。该对象可能是由类初始化程序创建的,并且可以从静态字段访问。您可以使用选项 --initialize-at-build-time= 在映像运行时请求类初始化。或者您可以编写自己的初始化方法并从主入口点显式调用它们。详细信息:Trace: object org.apache.avro.specific.SpecificDatumReader

非常感谢任何帮助。

4

2 回答 2

1

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

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

  1. 添加@io.quarkus.runtime.annotations.RegisterForReflection注释
  2. 使用延迟初始化初始化构造函数中的静态变量。
  3. 从运行时类 init 中删除这些类。缺点是您必须维护自定义代码生成模板。不过,这相对容易,这是自动化代码生成的 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找到基本模板

于 2020-02-12T21:05:48.153 回答
0

抱歉,我迟到了,但你在这里遇到的问题是,当你要求SpecificDatumReader在运行时初始化时,另一个在构建时初始化的类需要SpecificDatumReader初始化。

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

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

于 2020-02-12T19:47:53.973 回答