When building a native quarkus image, how should I (re-)structure my code to enable runtime class initialization?

huangapple go评论74阅读模式
英文:

When building a native quarkus image, how should I (re-)structure my code to enable runtime class initialization?

问题

我正在使用Quarkus构建本地镜像,但Graal分析失败并显示以下错误:

错误: 不允许在镜像堆中存在sun.security.provider.NativePRNG的实例因为此类应在镜像运行时初始化该对象已经在没有本地镜像初始化工具的情况下进行了初始化无法跟踪堆栈跟踪
详细消息
跟踪对象通过以下方式访问
        读取常量java.security.SecureRandom@472a6481的字段java.security.SecureRandom.secureRandomSpi
        扫描方法com.nimbusds.oauth2.sdk.id.Identifier.<init>(Identifier.java:112)达到
从入口点到com.nimbusds.oauth2.sdk.id.Identifier.<init>(int)的调用路径
        在com.nimbusds.oauth2.sdk.id.Identifier.<init>(Identifier.java:105)
        在com.nimbusds.oauth2.sdk.token.Token.<init>(Token.java:62)
        在com.nimbusds.oauth2.sdk.token.AccessToken.<init>(AccessToken.java:121)
        在com.nimbusds.oauth2.sdk.token.BearerAccessToken.<init>(BearerAccessToken.java:114)
        在ff.service.identity.application.OAuthAccessTokenProvider.generateAccessToken(OAuthAccessTokenProvider.java:78)
        在ff.service.identity.application.OAuthAccessTokenProvider.completeAccessTokenGeneration(OAuthAccessTokenProvider.java:62)
        在ff.service.identity.application.OAuthAccessTokenProvider_ClientProxy.completeAccessTokenGeneration(OAuthAccessTokenProvider_ClientProxy.zig:198)
        在ff.service.identity.application.OAuthService.validateSignedChallenge(OAuthService.java:187)
        在ff.service.identity.application.OAuthService_Subclass.validateSignedChallenge$$superaccessor1(OAuthService_Subclass.zig:258)
        在ff.service.identity.application.OAuthService_Subclass$$function$$1.apply(OAuthService_Subclass$$function$$1.zig:41)
        在sun.security.ec.XECParameters$1.get(XECParameters.java:183)
        在com.oracle.svm.core.jdk.SystemPropertiesSupport.initializeLazyValue(SystemPropertiesSupport.java:190)
        在com.oracle.svm.core.jdk.SystemPropertiesSupport.getProperty(SystemPropertiesSupport.java:143)
        在com.oracle.svm.core.jdk.Target_java_lang_System.getProperty(JavaLangSubstitutions.java:345)
        在com.oracle.svm.jni.JNIJavaCallWrappers.jniInvoke_ARRAY:Ljava_lang_System_2_0002egetProperty_00028Ljava_lang_String_2_00029Ljava_lang_String_2(generated:0)

它正确地明确表示应在运行时初始化随机数生成器提供程序的类。但是,与文档中不同,没有给出调用路径,因为:

> 该对象已经在没有本地镜像初始化工具的情况下进行了初始化,无法跟踪堆栈跟踪

我不知道如何重新组织我的代码以支持此操作,而且据我所知,我并没有做什么非常奇怪的事情。为了准备这个问题,我将涉及com.nimbusds类的代码粗暴地移动到了OAuthServiceOAuthAccessTokenProvider中。OAuthService仅由我的OAuthResouce使用,即使将这两个服务都标记为@RequestScoped以强制延迟初始化,错误消息仍然没有变化。

当我添加--initialize-at-run-time=ff.service.identity.application.OAuthService时,实际上会收到有关观察到的问题的更少信息。

错误: 在构建镜像期间初始化应在运行时初始化的类
 ff.service.identity.application.OAuthService该类被要求在运行时初始化来自命令行)。ff.service.identity.application.OAuthService已经在没有本地镜像初始化工具的情况下进行了初始化无法跟踪堆栈跟踪请尝试避免初始化导致ff.service.identity.application.OAuthService初始化的类

com.oracle.svm.core.util.UserError$UserException: 在构建镜像期间初始化应在运行时初始化的类
 ff.service.identity.application.OAuthService该类被要求在运行时初始化来自命令行)。ff.service.identity.application.OAuthService已经在没有本地镜像初始化工具的情况下进行了初始化无法跟踪堆栈跟踪请尝试避免初始化导致ff.service.identity.application.OAuthService初始化的类

        在com.oracle.svm.core.util.UserError.abort(UserError.java:68)
        在com.oracle.svm.hosted.classinitialization.ConfigurableClassInitialization.checkDelayedInitialization(ConfigurableClassInitialization.java:518)
        在com.oracle.svm.hosted.classinitialization.ClassInitializationFeature.duringAnalysis(ClassInitializationFeature.java:187)
        在com.oracle.svm.hosted.NativeImageGenerator.lambda$runPointsToAnalysis$8(NativeImageGenerator.java:720)
        在com.oracle.svm.hosted.FeatureHandler.forEachFeature(FeatureHandler.java:70)
        在com.oracle.svm.hosted.NativeImageGenerator.runPointsToAnalysis(NativeImageGenerator.java:720)
        在com.oracle.svm.hosted.NativeImageGenerator.doRun(NativeImageGenerator.java:538)
        在com.oracle.svm.hosted.NativeImageGenerator.lambda$run$0(NativeImageGenerator.java:451)
        在java.base/java.util.concurrent.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1407)
        在java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
        在java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
        在java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
        在java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
        在java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:177)

我应该避免初始化这些类,但我不知道我做错了什么或其他可能性。我忽略了什么吗?

编辑: 我正在使用Quarkus 1.6.1.Final,使用GraalVM版本20.1.0(Java版本11.0.7)。与--rerun-class-initialization-at-runtime标志相关的解决方案实际上已经被弃用,自GraalVM 19.0.0以来(我找不到链接):

> 警告:使用已弃用的选

英文:

I'm building a native image with quarkus and the graal analysis fails with the error:

Error: No instances of sun.security.provider.NativePRNG are allowed in the image heap as this class should be initialized at image runtime. Object has been initialized without the native-image initialization instrumentation and the stack trace can&#39;t be tracked.
Detailed message:                                                                                                                                                                                                                                                    
Trace: Object was reached by                                                                                                      
        reading field java.security.SecureRandom.secureRandomSpi of                                                               
                constant java.security.SecureRandom@472a6481 reached by                                                                                                                                                                                              
        scanning method com.nimbusds.oauth2.sdk.id.Identifier.&lt;init&gt;(Identifier.java:112)                                                                                                                                                                            
Call path from entry point to com.nimbusds.oauth2.sdk.id.Identifier.&lt;init&gt;(int):                                                                                                                                                                                     
        at com.nimbusds.oauth2.sdk.id.Identifier.&lt;init&gt;(Identifier.java:105)                                                                                                                                                                                         
        at com.nimbusds.oauth2.sdk.token.Token.&lt;init&gt;(Token.java:62)                                                                                                                                                                                                 
        at com.nimbusds.oauth2.sdk.token.AccessToken.&lt;init&gt;(AccessToken.java:121)                                                                                                                                                                                    
        at com.nimbusds.oauth2.sdk.token.BearerAccessToken.&lt;init&gt;(BearerAccessToken.java:114)                                                                                                                                                                        
        at ff.service.identity.application.OAuthAccessTokenProvider.generateAccessToken(OAuthAccessTokenProvider.java:78)                                                                                                                                            
        at ff.service.identity.application.OAuthAccessTokenProvider.completeAccessTokenGeneration(OAuthAccessTokenProvider.java:62)                                                                                                                                  
        at ff.service.identity.application.OAuthAccessTokenProvider_ClientProxy.completeAccessTokenGeneration(OAuthAccessTokenProvider_ClientProxy.zig:198)                                                                                                          
        at ff.service.identity.application.OAuthService.validateSignedChallenge(OAuthService.java:187)                                                                                                                                                               
        at ff.service.identity.application.OAuthService_Subclass.validateSignedChallenge$$superaccessor1(OAuthService_Subclass.zig:258)                                                                                                                              
        at ff.service.identity.application.OAuthService_Subclass$$function$$1.apply(OAuthService_Subclass$$function$$1.zig:41)                                                                                                                                       
        at sun.security.ec.XECParameters$1.get(XECParameters.java:183)                                                            
        at com.oracle.svm.core.jdk.SystemPropertiesSupport.initializeLazyValue(SystemPropertiesSupport.java:190)                                                                                                                                                     
        at com.oracle.svm.core.jdk.SystemPropertiesSupport.getProperty(SystemPropertiesSupport.java:143)                                                                                                                                                             
        at com.oracle.svm.core.jdk.Target_java_lang_System.getProperty(JavaLangSubstitutions.java:345)                                                                                                                                                               
        at com.oracle.svm.jni.JNIJavaCallWrappers.jniInvoke_ARRAY:Ljava_lang_System_2_0002egetProperty_00028Ljava_lang_String_2_00029Ljava_lang_String_2(generated:0)

It correctly and logically states that the class for the random number generator provider should be initialised at runtime. However, unlike in the docs, no call path is given because the:

> Object has been initialized without the native-image initialization instrumentation and the stack trace can't be tracked

I don't know how to go about restructuring my code to support this, and I'm not doing anything really exotic, as far as I can tell. To prepare this question, I brutally moved the code together involving classes from com.nimbusds, and it now resides in OAuthService and OAuthAccessTokenProvider. OAuthService is only used by my OAuthResouce, and even after making these two services @RequestScoped to enforce lazy initialization, the error message remains unchanged.

When I add --initialize-at-run-time=ff.service.identity.application.OAuthService, I actually receive less information about the observed problem.

Error: Classes that should be initialized at run time got initialized during image building:
 ff.service.identity.application.OAuthService the class was requested to be initialized at run time (from the command line). ff.service.identity.application.OAuthService has been initialized without the native-image initialization instrumentation and the stack trace can&#39;t be tracked. Try avoiding to initialize the class that caused initialization of ff.service.identity.application.OAuthService

com.oracle.svm.core.util.UserError$UserException: Classes that should be initialized at run time got initialized during image building:
 ff.service.identity.application.OAuthService the class was requested to be initialized at run time (from the command line). ff.service.identity.application.OAuthService has been initialized without the native-image initialization instrumentation and the stack trace can&#39;t be tracked. Try avoiding to initialize the class that caused initialization of ff.service.identity.application.OAuthService

        at com.oracle.svm.core.util.UserError.abort(UserError.java:68)
        at com.oracle.svm.hosted.classinitialization.ConfigurableClassInitialization.checkDelayedInitialization(ConfigurableClassInitialization.java:518)
        at com.oracle.svm.hosted.classinitialization.ClassInitializationFeature.duringAnalysis(ClassInitializationFeature.java:187)
        at com.oracle.svm.hosted.NativeImageGenerator.lambda$runPointsToAnalysis$8(NativeImageGenerator.java:720)
        at com.oracle.svm.hosted.FeatureHandler.forEachFeature(FeatureHandler.java:70)
        at com.oracle.svm.hosted.NativeImageGenerator.runPointsToAnalysis(NativeImageGenerator.java:720)
        at com.oracle.svm.hosted.NativeImageGenerator.doRun(NativeImageGenerator.java:538)
        at com.oracle.svm.hosted.NativeImageGenerator.lambda$run$0(NativeImageGenerator.java:451)
        at java.base/java.util.concurrent.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1407)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
        at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
        at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
        at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
        at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:177)

I'm supposted to avoid initializing these classes, but I don't know what I'm doing wrong or what other possibilities exist. What have I overseen?

EDIT: I am building with Quarkus 1.6.1.Final, using GraalVM Version 20.1.0 (Java Version 11.0.7).

A solution involving the flag --rerun-class-initialization-at-runtime is actually deprecated since GraalVM 19.0.0 (I can't find a link):

> Warning: Using a deprecated option --rerun-class-initialization-at-runtime. Currently there is no replacement for this option. Try using --initialize-at-run-time or use the non-API option -H:ClassInitialization directly.

答案1

得分: 1

你可能需要使用 rerun-class-initialization-at-runtime= com.nimbusds.oauth2.sdk.id.Identifier

英文:

Most likely you need to use rerun-class-initialization-at-runtime= com.nimbusds.oauth2.sdk.id.Identifier

huangapple
  • 本文由 发表于 2020年7月29日 22:08:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/63155550.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定