【问题标题】:When building a native quarkus image, how should I (re-)structure my code to enable runtime class initialization?在构建原生 quarkus 映像时,我应该如何(重新)构造我的代码以启用运行时类初始化?
【发布时间】:2020-07-29 14:08:39
【问题描述】:

我正在使用 quarkus 构建原生映像,但 graal 分析失败并出现错误:

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'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.<init>(Identifier.java:112)                                                                                                                                                                            
Call path from entry point to com.nimbusds.oauth2.sdk.id.Identifier.<init>(int):                                                                                                                                                                                     
        at com.nimbusds.oauth2.sdk.id.Identifier.<init>(Identifier.java:105)                                                                                                                                                                                         
        at com.nimbusds.oauth2.sdk.token.Token.<init>(Token.java:62)                                                                                                                                                                                                 
        at com.nimbusds.oauth2.sdk.token.AccessToken.<init>(AccessToken.java:121)                                                                                                                                                                                    
        at com.nimbusds.oauth2.sdk.token.BearerAccessToken.<init>(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)

它正确且合乎逻辑地声明随机数生成器提供程序的类应在运行时初始化。但是,与docs 不同,没有给出调用路径,因为:

对象已在没有原生映像初始化工具的情况下进行了初始化,并且无法跟踪堆栈跟踪

我不知道如何重构我的代码来支持这一点,而且据我所知,我并没有做任何真正奇特的事情。为了准备这个问题,我粗暴地将涉及类的代码从com.nimbusds 移到一起,现在它位于OAuthServiceOAuthAccessTokenProviderOAuthService只被我的OAuthResouce使用,即使使这两个服务@RequestScoped强制延迟初始化,错误信息仍然没有改变。

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

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'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'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)

我应该避免初始化这些类,但我不知道我做错了什么或存在哪些其他可能性。我监督了什么?

编辑:我正在使用 Quarkus 1.6.1.Final 构建,使用 GraalVM 版本 20.1.0(Java 版本 11.0.7)。

涉及标志 --rerun-class-initialization-at-runtime 的解决方案实际上自 GraalVM 19.0.0 以来已被弃用(我找不到链接):

警告:使用已弃用的选项 --rerun-class-initialization-at-runtime。目前没有替代此选项。尝试使用 --initialize-at-run-time 或直接使用非 API 选项 -H:ClassInitialization。

【问题讨论】:

    标签: java quarkus graalvm graalvm-native-image


    【解决方案1】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-17
      • 1970-01-01
      • 2011-11-17
      • 2011-07-01
      相关资源
      最近更新 更多