GraalVM Native build needs runtime initialization command line parameters #1449
Replies: 6 comments
-
Marking this as "Enhancement" since you are asking for us to support GraalVM |
Beta Was this translation helpful? Give feedback.
-
This is due to usage of SecureRandom in the If you experience issues with azure identity after the build you'll need to work with that team to understand why it's failing.
|
Beta Was this translation helpful? Give feedback.
-
Hi @jamdavi. Thank You for the reply . I tried to build the native image using the changes you suggested and the build was success. But when deploying the native image i now get some errors from Azure Identity dependency . This is basically due to non-availability of http client . When adding the http client dependency , the build fails. Similar but not exactly same error was found when i tried for jvm build . Let me know in case of any updates |
Beta Was this translation helpful? Give feedback.
-
@uttamsingh0107 I believe you have an internal ticket open on this and I'll respond with this same information there. I'll also close this issue based on my findings below. But this will be helpful for anyone else who needs this information. I was able to get this to build with the following changes.
So, the question is, Is the build failing because there's a problem with my app or a dependency? And, when we do get it working it will fail when you run the app? Is this a problem with the IoT SDK? The Azure SDK? Netty? Short answer No. The Long Answer Since GraalVM (GVM) does ahead-of-time compilation, there are bound to be limitations and concerns about the system it's compiled on and the one it's compiled for. A very obvious example would be if I did a local native compile on Windows it won't work for Linux. Similarly, but more nuanced is, if I built on Linux with a 2.0 kernel it likely won't work on a 5.0 kernel. Just as with platform implementation, the same applies for CPU architectures and endianness. GVM has a a large set of rules that it looks out for. You've been hit by two of them which are documented: SecureRandomSince From the docs:
GVM's requirement is that Initialization at build timeIf you notice in the build parameters above all but three Microsoft owned classes are specified. For all classes listed they are specified because they initialize SecureRandom in some way, but others are specified because they potentially initialize other classes that are not considered safe, or are unknown to GraalVM. This is another requirement of ahead-of-time compilation and not due to a specific library implementation. ConclusionThe exercises I did to get the build working required no changes to your application code, nor the Microsoft SDKs. But instead, required me to follow the GVM instructions and do some iterative changes to the build parameters to satisfy the GraalVM build. The same will be true for runtime exceptions, if libraries (like, azure-core-http-netty) are not included things will fail. If an library has platform dependent native hooks they might also fail. The amount and depth of errors that arise from dependent classes we use is all due to how GVM handles ahead-of-time compilation and not because our library doesn't officially support GVM. Officially, we haven't tested with GraalVM. There are likely scenarios and edge cases that won't work without some deep investgation. But, the exercises performed while investigating this ticket state that we likely do handle the majority of cases when GVM is setup correctly. The ground work would need to be done by the user of GVM to get the application built and run. Once we start seeing callstacks that point to our SDK not handling a specific scenario we can start to narrow down the issues. For now the problems are not specific to our SDK and need GraalVM experts to get the application stood up. |
Beta Was this translation helpful? Give feedback.
-
@jamdavi -> Thankyou for detailed answer. Couple of comments- this issue was created to get a graalvm compatible sdk. It is well known that graalvm does build time class initialization as you mentioned which is not a limitation but a trade off that developer decides for very low startup times(8x-10x lower time than jvm) and lower processing times. Thats what high performance and low footprint langs like golang and rust will do. So it is not definitely a limitation but a choice according to app requirements. Now coming to making secure random work with graalvm requires changes and recommendations from graalvm experts. This was the intent of creating the github issue in the first place. Also -> there have been multiple libs that already use secure random and have been modified to work with graalvm. i would want to reopen the ticket. |
Beta Was this translation helpful? Give feedback.
-
All instances of It appears that we can get a build with the existing SDK using well supported and documented methods. I will move this issue to a discussion as it's a large feature request and might need to be part of our v2 efforts. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
I was trying to authenticate a serviceclient using service principal . On using the azure-identity dependency , it builds a lot of reflections . I tried removing them using lazy initialization by using the --initialize-at-run-time , but even after including the java.security.SecureRandom class in the args , the class gets initialized at build time ,resulting a build failure. Without using azure identityin pom for service principal authentication, i was able to build a native build with a fully functional service client(Service client with Connection String). Please check the reproducer code's application.properties file for further details
Steps to reproduce the issue:
Reproducing the issue:
Clone the project from
(https://github.com/uttamsingh0107/quarkus-reproducable)
2.Run the command "mvn package -Pnative -Dquarkus.native.container-build=true"
Expected Output :
Build should be success
Actual Output:
/project:z --name build-native-dHJoo quay.io/quarkus/ubi-quarkus-native-image:21.3-java11 -J-Djava.util.logging.manager=org.jboss.logmanager.LogManager -J-Dsun.nio.ch.maxUpdateArraySize=100 -J-Dvertx.logger-delegate-factory-class-name=io.quarkus.vertx.core.runtime.VertxLogDelegateFactory -J-Dvertx.disableDnsResolver=true -J-Dio.netty.leakDetection.level=DISABLED -J-Dio.netty.allocator.maxOrder=3 -J-Duser.language=en -J-Duser.country=US -J-Dfile.encoding=UTF-8 -H:-ParseOnce --initialize-at-run-time=com.microsoft.aad.msal4jextensions.persistence.linux.ISecurityLibrary,com.microsoft.aad.msal4jextensions.persistence.mac.ISecurityLibrary,com.sun.jna.platform.win32.Crypt32,com.sun.jna.platform.win32.Kernel32,java.security.SecureRandom,com.nimbusds.jwt.JWTClaimsSet --trace-class-initialization=java.security.SecureRandom -H:InitialCollectionPolicy=com.oracle.svm.core.genscavenge.CollectionPolicy$BySpaceAndTime -H:+JNI -H:+AllowFoldMethods -H:FallbackThreshold=0 -H:+ReportExceptionStackTraces -H:-AddAllCharsets -H:EnableURLProtocols=http -H:-UseServiceLoaderFeature -H:+StackTrace -H:AdditionalSecurityProviders=com.sun.security.sasl.Provider,org.apache.kafka.common.security.oauthbearer.internals.OAuthBearerSaslClientProvider,org.apache.kafka.common.security.scram.internals.ScramSaslClientProvider 2.0v-runner -jar 2.0v-runner.jar
[2.0v-runner:25] classlist: 8,111.60 ms, 2.68 GB
[2.0v-runner:25] (cap): 682.64 ms, 2.68 GB
[2.0v-runner:25] setup: 2,899.51 ms, 2.68 GB
11:12:21,924 INFO [com.azu.cor.imp.jac.JacksonVersion] Package versions: jackson-annotations=2.12.5, jackson-core=2.12.5, jackson-databind=2.12.5, jackson-dataformat-xml=2.12.5, jackson-datatype-jsr310=2.12.5, azure-core=1.21.0
To see how the classes got initialized, use --trace-class-initialization=java.security.SecureRandom
[nm-iot-egress-2.0v-runner:25] analysis: 9,061.83 ms, 2.64 GB
Error: Classes that should be initialized at run time got initialized during image building:
java.security.SecureRandom the class was requested to be initialized at run time (from the command line with 'java.security.SecureRandom'). To see why java.security.SecureRandom got initialized use --trace-class-initialization=java.security.SecureRandom
com.oracle.svm.core.util.UserError$UserException: Classes that should be initialized at run time got initialized during image building:
java.security.SecureRandom the class was requested to be initialized at run time (from the command line with 'java.security.SecureRandom'). To see why java.security.SecureRandom got initialized use --trace-class-initialization=java.security.SecureRandom
at com.oracle.svm.core.util.UserError.abort(UserError.java:73)
at com.oracle.svm.hosted.classinitialization.ConfigurableClassInitialization.checkDelayedInitialization(ConfigurableClassInitialization.java:555)
at com.oracle.svm.hosted.classinitialization.ClassInitializationFeature.duringAnalysis(ClassInitializationFeature.java:168)
at com.oracle.svm.hosted.NativeImageGenerator.lambda$runPointsToAnalysis$12(NativeImageGenerator.java:727)
at com.oracle.svm.hosted.FeatureHandler.forEachFeature(FeatureHandler.java:73)
at com.oracle.svm.hosted.NativeImageGenerator.runPointsToAnalysis(NativeImageGenerator.java:727)
at com.oracle.svm.hosted.NativeImageGenerator.doRun(NativeImageGenerator.java:529)
at com.oracle.svm.hosted.NativeImageGenerator.run(NativeImageGenerator.java:488)
at com.oracle.svm.hosted.NativeImageGeneratorRunner.buildImage(NativeImageGeneratorRunner.java:403)
at com.oracle.svm.hosted.NativeImageGeneratorRunner.build(NativeImageGeneratorRunner.java:569)
at com.oracle.svm.hosted.NativeImageGeneratorRunner.main(NativeImageGeneratorRunner.java:122)
at com.oracle.svm.hosted.NativeImageGeneratorRunner$JDK9Plus.main(NativeImageGeneratorRunner.java:599)
[nm-iot-egress-2.0v-runner:25] [total]: 20,469.69 ms, 2.64 GB
Printing build artifacts to: /project/nm-iot-egress-2.0v-runner.build_artifacts.txt
Error: Image build request failed with exit status 1
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 46.364 s
[INFO] Finished at: 2021-12-02T16:42:25+05:30
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal io.quarkus:quarkus-maven-plugin:2.5.0.Final:build (default) on project nm-iot-egress: Failed to build quarkus application: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
[ERROR] [error]: Build step io.quarkus.deployment.pkg.steps.NativeImageBuildStep#build threw an exception: java.lang.RuntimeException: Failed to build native image
[ERROR] at io.quarkus.deployment.pkg.steps.NativeImageBuildStep.build(NativeImageBuildStep.java:233)
[ERROR] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[ERROR] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[ERROR] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[ERROR] at java.base/java.lang.reflect.Method.invoke(Method.java:566)
[ERROR] at io.quarkus.deployment.ExtensionLoader$2.execute(ExtensionLoader.java:887)
[ERROR] at io.quarkus.builder.BuildContext.run(BuildContext.java:277)
[ERROR] at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
[ERROR] at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2449)
[ERROR] at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1478)
[ERROR] at java.base/java.lang.Thread.run(Thread.java:829)
[ERROR] at org.jboss.threads.JBossThread.run(JBossThread.java:501)
[ERROR] Caused by: java.lang.RuntimeException: Image generation failed. Exit code: 1
[ERROR] at io.quarkus.deployment.pkg.steps.NativeImageBuildStep.imageGenerationFailed(NativeImageBuildStep.java:369)
[ERROR] at io.quarkus.deployment.pkg.steps.NativeImageBuildStep.build(NativeImageBuildStep.java:213)
[ERROR] ... 11 more
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1
Beta Was this translation helpful? Give feedback.
All reactions