Problem

Executing./gradlew bootBuildImage will cause a exception.

Caused by: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: No instances of ch.qos.logback.classic.Logger 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=ch.qos.logback.classic.Logger.

Executing ./gradlew nativeCompile will build successfully, but instead of producing an executable file, producing something like the following

flycat-price.build_artifacts.txt graal_isolate.h
flycat-price.dylib               graal_isolate_dynamic.h
flycat-price.h                   reports
flycat-price_dynamic.h

Config

    apply plugin: "org.graalvm.buildtools.native"
    graalvmNative {
        binaries {
            main {
                imageName.set('flycat-price')
                buildArgs.add('--trace-class-initialization=ch.qos.logback.classic.Logger')
                buildArgs.add('--trace-object-instantiation=ch.qos.logback.core.AsyncAppenderBase$Worker')
                buildArgs.add('--initialize-at-build-time=org.slf4j.LoggerFactory,ch.qos.logback')
                buildArgs.add('--initialize-at-run-time=io.netty')
            }
        }
    }

Error

    [creator]     Fatal error: com.oracle.graal.pointsto.util.AnalysisError$ParsingError: Error encountered while parsing io.netty.util.HashedWheelTimer.<init>(java.util.concurrent.ThreadFactory, long, java.util.concurrent.TimeUnit, int, boolean, long, java.util.concurrent.Executor)
    [creator]     Parsing context:
    [creator]        at io.netty.util.HashedWheelTimer.<init>(HashedWheelTimer.java:280)
    [creator]        at io.netty.util.HashedWheelTimer.<init>(HashedWheelTimer.java:251)
    [creator]
    [creator]           at com.oracle.graal.pointsto.util.AnalysisError.parsingError(AnalysisError.java:152)
    [creator]           at com.oracle.graal.pointsto.flow.MethodTypeFlow.createFlowsGraph(MethodTypeFlow.java:104)
    [creator]           at com.oracle.graal.pointsto.flow.MethodTypeFlow.ensureFlowsGraphCreated(MethodTypeFlow.java:83)
    [creator]           at com.oracle.graal.pointsto.flow.MethodTypeFlow.getOrCreateMethodFlowsGraph(MethodTypeFlow.java:65)
    [creator]           at com.oracle.graal.pointsto.typestate.DefaultSpecialInvokeTypeFlow.onObservedUpdate(DefaultSpecialInvokeTypeFlow.java:61)
    [creator]           at com.oracle.graal.pointsto.flow.TypeFlow.update(TypeFlow.java:558)
    [creator]           at com.oracle.graal.pointsto.PointsToAnalysis$1.run(PointsToAnalysis.java:635)
    [creator]           at com.oracle.graal.pointsto.util.CompletionExecutor.executeCommand(CompletionExecutor.java:193)
    [creator]           at com.oracle.graal.pointsto.util.CompletionExecutor.lambda$executeService$0(CompletionExecutor.java:177)
    [creator]           at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1395)
    [creator]           at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373)
    [creator]           at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182)
    [creator]           at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655)
    [creator]           at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622)
    [creator]           at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165)
    [creator]     Caused by: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: No instances of ch.qos.logback.classic.Logger 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=ch.qos.logback.classic.Logger.
    [creator]           at com.oracle.svm.hosted.classinitialization.ClassInitializationFeature.checkImageHeapInstance(ClassInitializationFeature.java:140)
    [creator]           at com.oracle.graal.pointsto.meta.AnalysisUniverse.replaceObject(AnalysisUniverse.java:583)
    [creator]           at com.oracle.svm.hosted.ameta.AnalysisConstantReflectionProvider.replaceObject(AnalysisConstantReflectionProvider.java:257)
    [creator]           at com.oracle.svm.hosted.ameta.AnalysisConstantReflectionProvider.interceptValue(AnalysisConstantReflectionProvider.java:228)
    [creator]           at com.oracle.svm.hosted.ameta.AnalysisConstantReflectionProvider.readValue(AnalysisConstantReflectionProvider.java:105)
    [creator]           at com.oracle.svm.hosted.ameta.AnalysisConstantReflectionProvider.readFieldValue(AnalysisConstantReflectionProvider.java:84)
    [creator]           at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.util.ConstantFoldUtil$1.readValue(ConstantFoldUtil.java:55)
    [creator]           at jdk.internal.vm.compiler/org.graalvm.compiler.core.common.spi.JavaConstantFieldProvider.readConstantField(JavaConstantFieldProvider.java:78)
    [creator]           at com.oracle.svm.hosted.ameta.AnalysisConstantFieldProvider.readConstantField(AnalysisConstantFieldProvider.java:72)
    [creator]           at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.util.ConstantFoldUtil.tryConstantFold(ConstantFoldUtil.java:51)
    [creator]           at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.java.LoadFieldNode.asConstant(LoadFieldNode.java:178)
    [creator]           at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.java.LoadFieldNode.canonical(LoadFieldNode.java:144)
    [creator]           at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.java.LoadFieldNode.canonical(LoadFieldNode.java:135)
    [creator]           at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.java.LoadFieldNode.canonical(LoadFieldNode.java:72)
    [creator]           at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.spi.Canonicalizable$Unary.canonical(Canonicalizable.java:101)
    [creator]           at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.SimplifyingGraphDecoder.canonicalizeFixedNode(SimplifyingGraphDecoder.java:214)
    [creator]           at jdk.internal.vm.compiler/org.graalvm.compiler.replacements.PEGraphDecoder.canonicalizeFixedNode(PEGraphDecoder.java:1572)
    [creator]           at com.oracle.graal.pointsto.phases.InlineBeforeAnalysisGraphDecoder.canonicalizeFixedNode(InlineBeforeAnalysis.java:192)
    [creator]           at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.SimplifyingGraphDecoder.handleFixedNode(SimplifyingGraphDecoder.java:193)
    [creator]           at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.GraphDecoder.processNextNode(GraphDecoder.java:821)
    [creator]           at com.oracle.graal.pointsto.phases.InlineBeforeAnalysisGraphDecoder.processNextNode(InlineBeforeAnalysis.java:240)
    [creator]           at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.GraphDecoder.decode(GraphDecoder.java:548)
    [creator]           at jdk.internal.vm.compiler/org.graalvm.compiler.replacements.PEGraphDecoder.decode(PEGraphDecoder.java:833)
    [creator]           at com.oracle.graal.pointsto.phases.InlineBeforeAnalysis.decodeGraph(InlineBeforeAnalysis.java:98)
    [creator]           at com.oracle.graal.pointsto.flow.MethodTypeFlowBuilder.parse(MethodTypeFlowBuilder.java:176)
    [creator]           at com.oracle.graal.pointsto.flow.MethodTypeFlowBuilder.apply(MethodTypeFlowBuilder.java:343)
    [creator]           at com.oracle.graal.pointsto.flow.MethodTypeFlow.createFlowsGraph(MethodTypeFlow.java:93)
    [creator]           ... 13 more
    [creator]     --------------------------------------------------------------------------------

Version

❯ java --version
openjdk 17.0.5 2022-10-18 LTS
OpenJDK Runtime Environment GraalVM 22.3.0-dev (build 17.0.5+8-LTS)
OpenJDK 64-Bit Server VM GraalVM 22.3.0-dev (build 17.0.5+8-LTS, mixed mode, sharing)

~/Dropbox/Project/flycat-projects main*
❯ uname -a
Darwin MacBook-Air 21.6.0 Darwin Kernel Version 21.6.0: Mon Aug 22 20:20:07 PDT 2022; root:xnu-8020.140.49~2/RELEASE_ARM64_T8110 arm64

~/Dropbox/Project/flycat-projects main*
❯ ./gradlew --version

------------------------------------------------------------
Gradle 7.5.1
------------------------------------------------------------

Build time:   2022-08-05 21:17:56 UTC
Revision:     d1daa0cbf1a0103000b71484e1dbfe096e095918

Kotlin:       1.6.21
Groovy:       3.0.10
Ant:          Apache Ant(TM) version 1.10.11 compiled on July 10 2021
JVM:          17.0.5 (BellSoft 17.0.5+8-LTS)
OS:           Mac OS X 12.6 aarch64


Comment From: wilkinsona

It looks like you're using an M1 Mac where buildpacks are not yet supported.

For nativeCompile, your configuration doesn't look right to me. You shouldn't need to initialise SLF4J or Logback at build time. Does it work with the default configuration for the main GraalMV binary? If it does not and you would like us to spend some more time investigating, please spend some time providing a complete yet minimal sample that reproduces the problem. You can share it with us by pushing it to a separate repository on GitHub or by zipping it up and attaching it to this issue.

Comment From: zgqq

@wilkinsona For nativeCompile, after several hours of effort, finally reproduce the problem, may be due to org.springframework.boot:spring-boot-starter-data-redis this package, here sample https://github.com/zgqq/spring-boot-native-sample

nativeCompile files

  ~/Downloads/demo 2/build/native/nativeCompile main
❯ ls
flycat-price.build_artifacts.txt flycat-price_dynamic.h
flycat-price.dylib               graal_isolate.h
flycat-price.h                   graal_isolate_dynamic.h

Environment

❯ sw_vers
ProductName:    macOS
ProductVersion: 12.6
BuildVersion:   21G115

~/Dropbox/Project/flycat-projects main
❯ uname -a
Darwin MacBook-Air 21.6.0 Darwin Kernel Version 21.6.0: Mon Aug 22 20:20:07 PDT 2022; root:xnu-8020.140.49~2/RELEASE_ARM64_T8110 arm64

~/Dropbox/Project/flycat-projects main
❯ java --version
openjdk 17.0.5 2022-10-18 LTS
OpenJDK Runtime Environment GraalVM 22.3.0-dev (build 17.0.5+8-LTS)
OpenJDK 64-Bit Server VM GraalVM 22.3.0-dev (build 17.0.5+8-LTS, mixed mode, sharing)

Comment From: wilkinsona

Thanks for the sample. You have applied the java-library plugin. This tells the org.graalvm.buildtools.native plugin that you want your application to be compiled into a shared library. You can see this in the output of the nativeCompile task:

> Task :nativeCompile
[native-image-plugin] GraalVM Toolchain detection is disabled
[native-image-plugin] GraalVM location read from environment variable: JAVA_HOME
[native-image-plugin] Native Image executable path: /Library/Java/LibericaNativeImageKit/liberica-vm-core-22.3.0-openjdk17/Contents/Home/lib/svm/bin/native-image
========================================================================================================================
GraalVM Native Image: Generating 'flycat-price' (shared library)...
========================================================================================================================

You should just use the java plugin (which you have already applied) instead:

diff --git a/build.gradle b/build.gradle
index 01a7d87..a1b8a4d 100644
--- a/build.gradle
+++ b/build.gradle
@@ -20,7 +20,6 @@ repositories {
        maven { url 'https://repo.spring.io/milestone' }
 }

-apply plugin: 'java-library'
 dependencies {

 // https://mvnrepository.com/artifact/org.jetbrains.kotlinx/kotlinx-serialization-json
@@ -32,7 +31,7 @@ dependencies {
        // annotationProcessor 'org.projectlombok:lombok'
        testImplementation 'org.springframework.boot:spring-boot-starter-test'

-         api "org.springframework.boot:spring-boot-starter-data-redis"
+         implementation "org.springframework.boot:spring-boot-starter-data-redis"

         compileOnly 'org.projectlombok:lombok:1.18.24'
         annotationProcessor 'org.projectlombok:lombok:1.18.24'