quarkus: @RegisterForReflection cannot be added to --initialize-at-run-time=

Describe the bug Classes marked with @RegisterForReflection cannot be added to --initialize-at-run-time= because Quarkus attempts to initialize the classes at io.quarkus.runner.AutoFeature.beforeAnalysis(AutoFeature.zig:970) during a native image build.

Expected behavior I can annotate a class with @RegisterForReflection and also --initialize-at-run-time=.

Actual behavior In this case, myClass is generated with the avro maven plugin. I have customized the velocity template to annotate the class with @RegisterForReflection so I do not have to write out all the classes (there are a lot) in a reflection-config.json. That said, reflection-config.json seems to work just fine.

com.oracle.svm.core.util.UserError$UserException: Classes that should be initialized at run time got initialized during image building:
 myClass the class was requested to be initialized at build time (from the command line). myClass caused initialization of this class with the following trace: 
        at io.quarkus.runner.AutoFeature.beforeAnalysis(AutoFeature.zig:970)
        at com.oracle.svm.hosted.NativeImageGenerator.lambda$runPointsToAnalysis$7(NativeImageGenerator.java:670)
        at com.oracle.svm.hosted.FeatureHandler.forEachFeature(FeatureHandler.java:63)
        at com.oracle.svm.hosted.NativeImageGenerator.runPointsToAnalysis(NativeImageGenerator.java:670)
        at com.oracle.svm.hosted.NativeImageGenerator.doRun(NativeImageGenerator.java:526)
        at com.oracle.svm.hosted.NativeImageGenerator.lambda$run$0(NativeImageGenerator.java:444)
        at java.util.concurrent.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1386)
        at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
        at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
        at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
        at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)

        at com.oracle.svm.core.util.UserError.abort(UserError.java:65)
        at com.oracle.svm.hosted.classinitialization.ConfigurableClassInitialization.checkDelayedInitialization(ConfigurableClassInitialization.java:494)
        at com.oracle.svm.hosted.classinitialization.ClassInitializationFeature.duringAnalysis(ClassInitializationFeature.java:188)
        at com.oracle.svm.hosted.NativeImageGenerator.lambda$runPointsToAnalysis$8(NativeImageGenerator.java:711)
        at com.oracle.svm.hosted.FeatureHandler.forEachFeature(FeatureHandler.java:63)
        at com.oracle.svm.hosted.NativeImageGenerator.runPointsToAnalysis(NativeImageGenerator.java:711)
        at com.oracle.svm.hosted.NativeImageGenerator.doRun(NativeImageGenerator.java:526)
        at com.oracle.svm.hosted.NativeImageGenerator.lambda$run$0(NativeImageGenerator.java:444)
        at java.util.concurrent.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1386)
        at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
        at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
        at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
        at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)

To Reproduce Steps to reproduce the behavior:

  1. Create a class with @RegisterForReflection and add it to --initialize-at-run-time=
  2. mvn clean install -Dnative -Dquarkus.native.container-build=true
  3. See the stack track

Configuration

quarkus.native.additional-build-args=--initialize-at-run-time=my.package.avro,-H:+TraceClassInitialization


Environment (please complete the following information):

  • Output of uname -a or ver: Darwin Kernel Version 18.7.0: Sun Dec 1 18:59:03 PST 2019; root:xnu-4903.278.19~1/RELEASE_X86_64 x86_64
  • Output of java -version: openjdk version “1.8.0_212” OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_212-b03) OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.212-b03, mixed mode)
  • GraalVM version (if different from Java): 19.2.1-grl via sdkman
  • Quarkus version or git rev: 1.1.1.Final

Additional context It may be worth considering an avro extension to handle initialization and reflection for classes generated from avro schema.

As a work around, I’ve been able to further customize the velocity template for the avro generated code to move all the static initializers to the default constructor, which will incur the cost on the first time the class is instantiated. Ideally, this would not be required and we could do this work in a quarkus extension.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 20 (20 by maintainers)

Most upvoted comments

FYI, the problem was that reflection registration in quarkus was loading the class and initializing it at static-init. Fix was just to not initialize the class. My PR should fix it.

Funnily enough, there is an ongoing thread on the list: https://groups.google.com/forum/#!topic/quarkus-dev/VDJ6_Slc0yU . In the end, it might indeed be a bug or at least an undesired behavior.

That was it. I can confirm that the build issue is resolved with 1.3.0.Alpha2!

I am unable to deploy and test this app right now for other reasons, but given the patch and the nature of the issue, I think we are good to close this.

@gwenneg no. Thanks for letting me know. It’s been a really busy few days but will try to squeeze it in.

@gwenneg ok, that is useful info. I’m running some tests now and will report back.