Random/SplittableRandom 使用 optaplanner 构建 quarkus 原生镜像时出错

Random/SplittableRandom error while building quarkus native image with optaplanner

我在原生图像中构建我的 quarkus optaplanner 应用程序时遇到这个“Random/SplittableRandom”错误:

docker run --env LANG=C --rm -v /Users/user1/myapp/target/myapp-1.0.0-SNAPSHOT-native-image-source-jar:/project:z --name build-native-qOeJv quay.io/quarkus/ubi-quarkus-native-image:22.0.0-java11 -J-Dsun.nio.ch.maxUpdateArraySize=100 -J-Djava.util.logging.manager=org.jboss.logmanager.LogManager -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 -J--add-exports=java.security.jgss/sun.security.krb5=ALL-UNNAMED -J--add-opens=java.base/java.text=ALL-UNNAMED -H:InitialCollectionPolicy=com.oracle.svm.core.genscavenge.CollectionPolicy$BySpaceAndTime -H:+JNI -H:+AllowFoldMethods -J-Djava.awt.headless=true -H:FallbackThreshold=0 -H:+ReportExceptionStackTraces -H:-AddAllCharsets -H:EnableURLProtocols=http,https -H:+InlineBeforeAnalysis -H:-UseServiceLoaderFeature -H:+StackTrace myapp-1.0.0-SNAPSHOT-runner -jar myapp-1.0.0-SNAPSHOT-runner.jar

Error: Unsupported features in 2 methods
Detailed message:
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.  To see how this object got instantiated use --trace-object-instantiation=java.util.Random. 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.
Trace: Object was reached by 
    reading field java.util.Collections.r
Error: No instances of java.io.FilePermission are allowed in the image heap as this class should be initialized at image runtime. To see how this object got instantiated use --trace-object-instantiation=java.io.FilePermission.
Trace: Object was reached by 
    reading field java.util.concurrent.ConcurrentHashMap$Node.val of
        constant java.util.concurrent.ConcurrentHashMap$Node@2fa9569c reached by 
    indexing into array
        constant java.util.concurrent.ConcurrentHashMap$Node[]@37a65cb2 reached by 
    reading field java.util.concurrent.ConcurrentHashMap.table of
        constant java.util.concurrent.ConcurrentHashMap@2ade02d0 reached by 
    reading field java.io.FilePermissionCollection.perms of
        constant java.io.FilePermissionCollection@7a8b93fb reached by 
    reading field java.util.concurrent.ConcurrentHashMap$Node.val of
        constant java.util.concurrent.ConcurrentHashMap$Node@7cdf033 reached by 
    indexing into array
        constant java.util.concurrent.ConcurrentHashMap$Node[]@1a17f87 reached by 
    reading field java.util.concurrent.ConcurrentHashMap.table of
        constant java.util.concurrent.ConcurrentHashMap@3c16c45b reached by 
    reading field java.security.Permissions.permsMap of
        constant java.security.Permissions@51058af3 reached by 
    reading field java.security.ProtectionDomain.permissions of
        constant java.security.ProtectionDomain@14be23e7 reached by 
    scanning method org.drools.wiring.dynamic.PackageClassLoader.writeClass(PackageClassLoader.java:138)
Call path from entry point to org.drools.wiring.dynamic.PackageClassLoader.writeClass(String, byte[]): 
    at org.drools.wiring.dynamic.PackageClassLoader.writeClass(PackageClassLoader.java:138)
    at org.drools.wiring.dynamic.PackageClassLoader.internalDefineClass(PackageClassLoader.java:108)
    at org.drools.wiring.dynamic.PackageClassLoader.fastFindClass(PackageClassLoader.java:79)
    at org.drools.wiring.dynamic.PackageClassLoader.loadClass(PackageClassLoader.java:56)
    at com.oracle.svm.core.jdk.Target_java_lang_ClassLoader.loadClass(Target_java_lang_ClassLoader.java:141)
    at org.drools.ancompiler.KieBaseUpdaterANC.loadFromKJar(KieBaseUpdaterANC.java:86)
    at org.drools.ancompiler.KieBaseUpdaterANC.run(KieBaseUpdaterANC.java:56)
    at java.lang.Thread.run(Thread.java:829)
    at com.oracle.svm.core.thread.JavaThreads.threadStartRoutine(JavaThreads.java:597)
    at com.oracle.svm.core.posix.thread.PosixJavaThreads.pthreadStartRoutine(PosixJavaThreads.java:194)
    at com.oracle.svm.core.code.IsolateEnterStub.PosixJavaThreads_pthreadStartRoutine_e1f4a8c0039f8337338252cd8734f63a79b5e3df(generated:0)

com.oracle.svm.core.util.UserError$UserException: Unsupported features in 2 methods
Detailed message:
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.  To see how this object got instantiated use --trace-object-instantiation=java.util.Random. 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.
Trace: Object was reached by 
    reading field java.util.Collections.r
Error: No instances of java.io.FilePermission are allowed in the image heap as this class should be initialized at image runtime. To see how this object got instantiated use --trace-object-instantiation=java.io.FilePermission.
Trace: Object was reached by 
    reading field java.util.concurrent.ConcurrentHashMap$Node.val of
        constant java.util.concurrent.ConcurrentHashMap$Node@2fa9569c reached by 
    indexing into array
        constant java.util.concurrent.ConcurrentHashMap$Node[]@37a65cb2 reached by 
    reading field java.util.concurrent.ConcurrentHashMap.table of
        constant java.util.concurrent.ConcurrentHashMap@2ade02d0 reached by 
    reading field java.io.FilePermissionCollection.perms of
        constant java.io.FilePermissionCollection@7a8b93fb reached by 
    reading field java.util.concurrent.ConcurrentHashMap$Node.val of
        constant java.util.concurrent.ConcurrentHashMap$Node@7cdf033 reached by 
    indexing into array
        constant java.util.concurrent.ConcurrentHashMap$Node[]@1a17f87 reached by 
    reading field java.util.concurrent.ConcurrentHashMap.table of
        constant java.util.concurrent.ConcurrentHashMap@3c16c45b reached by 
    reading field java.security.Permissions.permsMap of
        constant java.security.Permissions@51058af3 reached by 
    reading field java.security.ProtectionDomain.permissions of
        constant java.security.ProtectionDomain@14be23e7 reached by 
    scanning method org.drools.wiring.dynamic.PackageClassLoader.writeClass(PackageClassLoader.java:138)
Call path from entry point to org.drools.wiring.dynamic.PackageClassLoader.writeClass(String, byte[]): 
    at org.drools.wiring.dynamic.PackageClassLoader.writeClass(PackageClassLoader.java:138)
    at org.drools.wiring.dynamic.PackageClassLoader.internalDefineClass(PackageClassLoader.java:108)
    at org.drools.wiring.dynamic.PackageClassLoader.fastFindClass(PackageClassLoader.java:79)
    at org.drools.wiring.dynamic.PackageClassLoader.loadClass(PackageClassLoader.java:56)
    at com.oracle.svm.core.jdk.Target_java_lang_ClassLoader.loadClass(Target_java_lang_ClassLoader.java:141)
    at org.drools.ancompiler.KieBaseUpdaterANC.loadFromKJar(KieBaseUpdaterANC.java:86)
    at org.drools.ancompiler.KieBaseUpdaterANC.run(KieBaseUpdaterANC.java:56)
    at java.lang.Thread.run(Thread.java:829)
    at com.oracle.svm.core.thread.JavaThreads.threadStartRoutine(JavaThreads.java:597)
    at com.oracle.svm.core.posix.thread.PosixJavaThreads.pthreadStartRoutine(PosixJavaThreads.java:194)
    at com.oracle.svm.core.code.IsolateEnterStub.PosixJavaThreads_pthreadStartRoutine_e1f4a8c0039f8337338252cd8734f63a79b5e3df(generated:0)

    at com.oracle.svm.core.util.UserError.abort(UserError.java:87)
    at com.oracle.svm.hosted.FallbackFeature.reportAsFallback(FallbackFeature.java:233)
    at com.oracle.svm.hosted.NativeImageGenerator.runPointsToAnalysis(NativeImageGenerator.java:731)
    at com.oracle.svm.hosted.NativeImageGenerator.doRun(NativeImageGenerator.java:537)
    at com.oracle.svm.hosted.NativeImageGenerator.run(NativeImageGenerator.java:494)
    at com.oracle.svm.hosted.NativeImageGeneratorRunner.buildImage(NativeImageGeneratorRunner.java:426)
    at com.oracle.svm.hosted.NativeImageGeneratorRunner.build(NativeImageGeneratorRunner.java:587)
    at com.oracle.svm.hosted.NativeImageGeneratorRunner.main(NativeImageGeneratorRunner.java:126)
    at com.oracle.svm.hosted.NativeImageGeneratorRunner$JDK9Plus.main(NativeImageGeneratorRunner.java:617)
Caused by: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: Unsupported features in 2 methods
Detailed message:
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.  To see how this object got instantiated use --trace-object-instantiation=java.util.Random. 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.
Trace: Object was reached by 
    reading field java.util.Collections.r
Error: No instances of java.io.FilePermission are allowed in the image heap as this class should be initialized at image runtime. To see how this object got instantiated use --trace-object-instantiation=java.io.FilePermission.
Trace: Object was reached by 
    reading field java.util.concurrent.ConcurrentHashMap$Node.val of
        constant java.util.concurrent.ConcurrentHashMap$Node@2fa9569c reached by 
    indexing into array
        constant java.util.concurrent.ConcurrentHashMap$Node[]@37a65cb2 reached by 
    reading field java.util.concurrent.ConcurrentHashMap.table of
        constant java.util.concurrent.ConcurrentHashMap@2ade02d0 reached by 
    reading field java.io.FilePermissionCollection.perms of
        constant java.io.FilePermissionCollection@7a8b93fb reached by 
    reading field java.util.concurrent.ConcurrentHashMap$Node.val of
        constant java.util.concurrent.ConcurrentHashMap$Node@7cdf033 reached by 
    indexing into array
        constant java.util.concurrent.ConcurrentHashMap$Node[]@1a17f87 reached by 
    reading field java.util.concurrent.ConcurrentHashMap.table of
        constant java.util.concurrent.ConcurrentHashMap@3c16c45b reached by 
    reading field java.security.Permissions.permsMap of
        constant java.security.Permissions@51058af3 reached by 
    reading field java.security.ProtectionDomain.permissions of
        constant java.security.ProtectionDomain@14be23e7 reached by 
    scanning method org.drools.wiring.dynamic.PackageClassLoader.writeClass(PackageClassLoader.java:138)
Call path from entry point to org.drools.wiring.dynamic.PackageClassLoader.writeClass(String, byte[]): 
    at org.drools.wiring.dynamic.PackageClassLoader.writeClass(PackageClassLoader.java:138)
    at org.drools.wiring.dynamic.PackageClassLoader.internalDefineClass(PackageClassLoader.java:108)
    at org.drools.wiring.dynamic.PackageClassLoader.fastFindClass(PackageClassLoader.java:79)
    at org.drools.wiring.dynamic.PackageClassLoader.loadClass(PackageClassLoader.java:56)
    at com.oracle.svm.core.jdk.Target_java_lang_ClassLoader.loadClass(Target_java_lang_ClassLoader.java:141)
    at org.drools.ancompiler.KieBaseUpdaterANC.loadFromKJar(KieBaseUpdaterANC.java:86)
    at org.drools.ancompiler.KieBaseUpdaterANC.run(KieBaseUpdaterANC.java:56)
    at java.lang.Thread.run(Thread.java:829)
    at com.oracle.svm.core.thread.JavaThreads.threadStartRoutine(JavaThreads.java:597)
    at com.oracle.svm.core.posix.thread.PosixJavaThreads.pthreadStartRoutine(PosixJavaThreads.java:194)
    at com.oracle.svm.core.code.IsolateEnterStub.PosixJavaThreads_pthreadStartRoutine_e1f4a8c0039f8337338252cd8734f63a79b5e3df(generated:0)

    at com.oracle.graal.pointsto.constraints.UnsupportedFeatures.report(UnsupportedFeatures.java:129)
    at com.oracle.svm.hosted.NativeImageGenerator.runPointsToAnalysis(NativeImageGenerator.java:728)
    ... 6 more

我搜索了一下,找到了这篇文章 working with randoms native image,但我仍然不知道我需要做什么来解决这个问题。

似乎 quarkus 试图为 drools 创建 Random 或 SplittableRandom 的实例 class,我使用的是 optaplanner quarkus,我不使用 drools 规则引擎,我使用约束流。

有没有人在为 optaplanner quarkus 应用程序构建原生镜像时遇到同样的问题?我应该怎么做才能克服这个问题?我试过graalvm 22.0和21.3,都有同样的问题。

提前感谢您的帮助。

下面这行告诉我你的类路径有问题:

Call path from entry point to org.drools.wiring.dynamic.PackageClassLoader.writeClass(String, byte[]): 

drools-wiring-dynamic 模块未设计为在本机模式下工作,需要替换为 drools-wiring-static。事实上,optaplanner-quarkus 模块会为您完成所有这些工作。

您使用的是 optaplanner-quarkus 而不是 optaplanner-core?堆栈跟踪告诉我你可能不是。如果是,我建议您找出 drools-wiring-dynamic 依赖项的来源,然后将其删除。

另一个问题来源可能是您试图在本机模式下使用约束 DRL。这不受支持,并且会因一个或另一个异常而失败。在本机模式下,您有三种约束选择 - 约束流、Java 增量或 Java 简单。