【问题标题】:Quarkus native build class in both build and run time initialization构建和运行时初始化中的 Quarkus 原生构建类
【发布时间】:2019-12-19 16:03:13
【问题描述】:

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

重现此内容的示例项目: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:+TraceClass初始化

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

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

非常感谢任何帮助。

【问题讨论】:

    标签: java quarkus graalvm-native-image


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

      抱歉,我迟到了,但您遇到的问题是,虽然您要求在运行时初始化 SpecificDatumReader,但在构建时初始化的另一个类需要初始化 SpecificDatumReader

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-07-15
        • 1970-01-01
        • 2016-09-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多