quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.35k stars 2.56k forks source link

Detected an instance of Random/SplittableRandom class in the image heap #41385

Open parasjain27031994 opened 1 week ago

parasjain27031994 commented 1 week ago

Describe the bug

I have a Quarkus application, that includes dependencies for both AWS and Azure EventHub. Since EventHub extension is not yet available and Azure SDK is GraalVM compatible, while building the native image I am getting following error

Error: Detected an instance of Random/SplittableRandom class in the image heap. Instances created during image generation have cached seed values and don't behave as expected. If these objects should not be stored in the image heap, you can use 
    '--trace-object-instantiation=java.security.SecureRandom'
to find classes that instantiate these objects. Once you found such a class, you can mark it explicitly for run time initialization with 
    '--initialize-at-run-time=<culprit>'
to prevent the instantiation of the object.
The object was probably created by a class initializer and is reachable from a static field. You can request class initialization at image runtime by using the option --initialize-at-run-time=<class-name>. Or you can write your own initialization methods and call them explicitly from your main entry point.
Detailed message:
Trace: Object was reached by
  trying to constant fold static field com.microsoft.azure.proton.transport.proxy.impl.DigestProxyChallengeProcessorImpl.SECURE_RANDOM
    at com.microsoft.azure.proton.transport.proxy.impl.DigestProxyChallengeProcessorImpl.computeDigestAuthHeader(DigestProxyChallengeProcessorImpl.java:143)
  parsing method com.microsoft.azure.proton.transport.proxy.impl.DigestProxyChallengeProcessorImpl.computeDigestAuthHeader(DigestProxyChallengeProcessorImpl.java:116) reachable via the parsing context
    at static root method.(Unknown Source)
com.oracle.svm.core.util.UserError$UserException: Detected an instance of Random/SplittableRandom class in the image heap. Instances created during image generation have cached seed values and don't behave as expected. If these objects should not be stored in the image heap, you can use 
    '--trace-object-instantiation=java.security.SecureRandom'
to find classes that instantiate these objects. Once you found such a class, you can mark it explicitly for run time initialization with 
    '--initialize-at-run-time=<culprit>'
to prevent the instantiation of the object.
The object was probably created by a class initializer and is reachable from a static field. You can request class initialization at image runtime by using the option --initialize-at-run-time=<class-name>. Or you can write your own initialization methods and call them explicitly from your main entry point.
Detailed message:
Trace: Object was reached by
  trying to constant fold static field com.microsoft.azure.proton.transport.proxy.impl.DigestProxyChallengeProcessorImpl.SECURE_RANDOM
    at com.microsoft.azure.proton.transport.proxy.impl.DigestProxyChallengeProcessorImpl.computeDigestAuthHeader(DigestProxyChallengeProcessorImpl.java:143)
  parsing method com.microsoft.azure.proton.transport.proxy.impl.DigestProxyChallengeProcessorImpl.computeDigestAuthHeader(DigestProxyChallengeProcessorImpl.java:116) reachable via the parsing context
    at static root method.(Unknown Source)
    at org.graalvm.nativeimage.builder/com.oracle.svm.core.util.UserError.abort(UserError.java:85)
    at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.FallbackFeature.reportAsFallback(FallbackFeature.java:248)
    at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGenerator.runPointsToAnalysis(NativeImageGenerator.java:814)
    at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGenerator.doRun(NativeImageGenerator.java:592)
    at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGenerator.run(NativeImageGenerator.java:550)
    at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGeneratorRunner.buildImage(NativeImageGeneratorRunner.java:539)
    at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGeneratorRunner.build(NativeImageGeneratorRunner.java:721)
    at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGeneratorRunner.start(NativeImageGeneratorRunner.java:143)
    at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGeneratorRunner.main(NativeImageGeneratorRunner.java:98)
Caused by: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: Detected an instance of Random/SplittableRandom class in the image heap. Instances created during image generation have cached seed values and don't behave as expected. If these objects should not be stored in the image heap, you can use 
    '--trace-object-instantiation=java.security.SecureRandom'
to find classes that instantiate these objects. Once you found such a class, you can mark it explicitly for run time initialization with 
    '--initialize-at-run-time=<culprit>'
to prevent the instantiation of the object.
The object was probably created by a class initializer and is reachable from a static field. You can request class initialization at image runtime by using the option --initialize-at-run-time=<class-name>. Or you can write your own initialization methods and call them explicitly from your main entry point.
Detailed message:
Trace: Object was reached by
  trying to constant fold static field com.microsoft.azure.proton.transport.proxy.impl.DigestProxyChallengeProcessorImpl.SECURE_RANDOM
    at com.microsoft.azure.proton.transport.proxy.impl.DigestProxyChallengeProcessorImpl.computeDigestAuthHeader(DigestProxyChallengeProcessorImpl.java:143)
  parsing method com.microsoft.azure.proton.transport.proxy.impl.DigestProxyChallengeProcessorImpl.computeDigestAuthHeader(DigestProxyChallengeProcessorImpl.java:116) reachable via the parsing context
    at static root method.(Unknown Source)
    at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.constraints.UnsupportedFeatures.report(UnsupportedFeatures.java:126)
    at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.NativeImageGenerator.runPointsToAnalysis(NativeImageGenerator.java:809)
    ... 6 more

The initial error was different and related to a conflict with reactor netty, so based on https://github.com/quarkusio/quarkus/issues/26879 I made following adjustments in my POM

 <dependency>
            <groupId>io.quarkiverse.azureservices</groupId>
            <artifactId>quarkus-azure-http-client-vertx</artifactId>
            <version>1.0.4</version>
        </dependency>
        <dependency>
            <groupId>com.azure</groupId>
            <artifactId>azure-messaging-eventhubs</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>com.azure</groupId>
                    <artifactId>azure-core-http-netty</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

I also defined below native image args

quarkus:
  native:
    additional-build-args: --initialize-at-run-time=com.microsoft.azure.proton.transport.ws.impl.Utils

However, after making the change, it is now throwing the above error.

Expected behavior

The native image build should succeed.

Actual behavior

THe native build fails

How to Reproduce?

No response

Output of uname -a or ver

No response

Output of java -version

graalvm-jdk-21+35.1

Mandrel or GraalVM version (if different from Java)

23.1.3.1-Final

Quarkus version or git rev

3.11.3

Build tool (ie. output of mvnw --version or gradlew --version)

Apache Maven 3.9.6 (bc0240f3c744dd6b6ec2920b3cd08dcc295161ae)

Additional information

No response

quarkus-bot[bot] commented 1 week ago

/cc @Karm (mandrel), @galderz (mandrel), @zakkak (mandrel)

Karm commented 1 week ago

@parasjain27031994 You need to use --trace-object-instantiation and perhaps also --trace-class-initialization to see the chain of what initializes what. Looking at source code also might help. You then mark the relevant classes for runtime initialization, e.g. in application.properties e.g.

quarkus.native.additional-build-args=\
-H:+UnlockExperimentalVMOptions,\
--initialize-at-run-time=\
some.package.SomeClass1\\,\
some.package.SomeClass2\\,\
some.package.SomeClass3,\
-H:-UnlockExperimentalVMOptions

Give it a shot and tell us if you need any assistance.

zakkak commented 6 days ago

@parasjain27031994 you might want to have a look at https://foivos.zakkak.net/tutorials/working-with-randoms-native-images/ (non-Quarkus specific blog post about this issue) as well.