Search code examples
javadroolsquarkusoptaplannergraalvm

Random/SplittableRandom error while building quarkus native image with optaplanner


I encounter this "Random/SplittableRandom" error while building my quarkus optaplanner application in a native image:

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

I searched and there is this article working with randoms native image but I still could not figure out what I need to do to resolve this.

Seems like quarkus tries to create an instance of Random or SplittableRandom for a drools class, I am using optaplanner quarkus and I do not use drools rule engine, I use constraint streams.

Does anyone have the same problem while building native image for optaplanner quarkus application? What should I do to overcome this? I tried graalvm 22.0 and 21.3, both have the same problem.

Thanks for your help in advance.


Solution

  • The following line tells me that there is a problem on your classpath:

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

    The drools-wiring-dynamic module is not designed to work in the native mode, and needs to be replaced by drools-wiring-static. In fact, the optaplanner-quarkus module does all this work for you.

    Are you using optaplanner-quarkus instead of optaplanner-core? The stack trace tells me you maybe aren't. If you are, I suggest you figure out the source of the drools-wiring-dynamic dependency, and remove it.

    One other source of problems may be that you are trying to use constraint DRL in native mode. That is not supported and will fail with one exception or another. In native mode, you have three choices for constraints - Constraint Streams, Java Incremental or Java Easy.