Search code examples
javanettygraalvm-native-image

GraalVM native image-image build error, report 'Error encountered while parsing io.netty.channel.nio.NioEventLoop.openSelector()'


Native image building environment: CentOS Linux release 7.9.2009 (Core), graalvm-ce-java17-22.3.0. The jar file is built by Zulu 17.0.5+8 (also tried 1.8) with NetBeans 15 on Windows 10. Netty dependencies:

    <dependency>
        <groupId>io.netty</groupId>
        <artifactId>netty-buffer</artifactId>
        <version>4.1.86.Final</version>
    </dependency>
    <dependency>
        <groupId>io.netty</groupId>
        <artifactId>netty-handler</artifactId>
        <version>4.1.86.Final</version>
    </dependency>
    <dependency>
        <groupId>io.netty</groupId>
        <artifactId>netty-codec-http</artifactId>
        <version>4.1.86.Final</version>
    </dependency>
    <dependency>
        <groupId>io.netty.incubator</groupId>
        <artifactId>netty-incubator-codec-native-quic</artifactId>
        <version>0.0.35.Final</version>
        <classifier>linux-x86_64</classifier>
    </dependency>

Error Message:

[root@secure-baud-2 ~]# native-image -jar myapp-1.0-jar-with-dependencies.jar myapp
========================================================================================================================
GraalVM Native Image: Generating 'myapp' (executable)...
========================================================================================================================
Warning: Could not register io.netty.handler.codec.compression.Lz4FrameDecoder: queryAllPublicMethods for reflection. Reason: java.lang.NoClassDefFoundError: net/jpountz/lz4/LZ4Exception.
Warning: Could not register io.netty.handler.codec.compression.Lz4FrameEncoder: queryAllPublicMethods for reflection. Reason: java.lang.NoClassDefFoundError: net/jpountz/lz4/LZ4Exception.
Warning: Could not register io.netty.handler.codec.marshalling.CompatibleMarshallingDecoder: queryAllPublicMethods for reflection. Reason: java.lang.NoClassDefFoundError: org/jboss/marshalling/ByteInput.
Warning: Could not register io.netty.handler.codec.marshalling.CompatibleMarshallingEncoder: queryAllPublicMethods for reflection. Reason: java.lang.NoClassDefFoundError: org/jboss/marshalling/ByteOutput.
Warning: Could not register io.netty.handler.codec.marshalling.MarshallingDecoder: queryAllPublicMethods for reflection. Reason: java.lang.NoClassDefFoundError: org/jboss/marshalling/ByteInput.
Warning: Could not register io.netty.handler.codec.marshalling.MarshallingEncoder: queryAllPublicMethods for reflection. Reason: java.lang.NoClassDefFoundError: org/jboss/marshalling/ByteOutput.
Warning: Could not register io.netty.handler.codec.protobuf.ProtobufDecoder: queryAllPublicMethods for reflection. Reason: java.lang.NoClassDefFoundError: com/google/protobuf/ExtensionRegistryLite.
Warning: Could not register io.netty.handler.codec.compression.Lz4FrameDecoder: queryAllPublicMethods for reflection. Reason: java.lang.NoClassDefFoundError: net/jpountz/lz4/LZ4Exception.
Warning: Could not register io.netty.handler.codec.compression.Lz4FrameEncoder: queryAllPublicMethods for reflection. Reason: java.lang.NoClassDefFoundError: net/jpountz/lz4/LZ4Exception.
Warning: Could not register io.netty.handler.codec.marshalling.CompatibleMarshallingDecoder: queryAllPublicMethods for reflection. Reason: java.lang.NoClassDefFoundError: org/jboss/marshalling/ByteInput.
Warning: Could not register io.netty.handler.codec.marshalling.CompatibleMarshallingEncoder: queryAllPublicMethods for reflection. Reason: java.lang.NoClassDefFoundError: org/jboss/marshalling/ByteOutput.
Warning: Could not register io.netty.handler.codec.marshalling.MarshallingDecoder: queryAllPublicMethods for reflection. Reason: java.lang.NoClassDefFoundError: org/jboss/marshalling/ByteInput.
Warning: Could not register io.netty.handler.codec.marshalling.MarshallingEncoder: queryAllPublicMethods for reflection. Reason: java.lang.NoClassDefFoundError: org/jboss/marshalling/ByteOutput.
Warning: Could not register io.netty.handler.codec.protobuf.ProtobufDecoder: queryAllPublicMethods for reflection. Reason: java.lang.NoClassDefFoundError: com/google/protobuf/ExtensionRegistryLite.
[1/7] Initializing...                                                                                   (20.5s @ 0.24GB)
 Version info: 'GraalVM 22.3.0 Java 17 CE'
 Java version info: '17.0.5+8-jvmci-22.3-b08'
 C compiler: gcc (redhat, x86_64, 4.8.5)
 Garbage collector: Serial GC
[2/7] Performing analysis...  []                                                                        (20.9s @ 0.18GB)
   1,273 (57.47%) of  2,215 classes reachable
     836 (28.14%) of  2,971 fields reachable
   3,577 (51.30%) of  6,973 methods reachable
      23 classes,     0 fields, and     0 methods registered for reflection

Fatal error: com.oracle.graal.pointsto.util.AnalysisError$ParsingError: Error encountered while parsing io.netty.channel.nio.NioEventLoop.openSelector()
Parsing context:
   at io.netty.channel.nio.NioEventLoop.openSelector(NioEventLoop.java:177)
   at io.netty.channel.nio.NioEventLoop.<init>(NioEventLoop.java:146)
   at io.netty.channel.nio.NioEventLoopGroup.newChild(NioEventLoopGroup.java:183)
   at io.netty.channel.nio.NioEventLoopGroup.newChild(NioEventLoopGroup.java:38)
   at io.netty.util.concurrent.MultithreadEventExecutorGroup.<init>(MultithreadEventExecutorGroup.java:84)
   at io.netty.util.concurrent.MultithreadEventExecutorGroup.<init>(MultithreadEventExecutorGroup.java:60)

        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.util.AnalysisError.parsingError(AnalysisError.java:153)
        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlow.createFlowsGraph(MethodTypeFlow.java:104)
        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlow.ensureFlowsGraphCreated(MethodTypeFlow.java:83)
        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlow.getOrCreateMethodFlowsGraph(MethodTypeFlow.java:65)
        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.typestate.DefaultSpecialInvokeTypeFlow.onObservedUpdate(DefaultSpecialInvokeTypeFlow.java:61)
        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.TypeFlow.update(TypeFlow.java:562)
        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.PointsToAnalysis$1.run(PointsToAnalysis.java:488)
        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.util.CompletionExecutor.executeCommand(CompletionExecutor.java:193)
        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.util.CompletionExecutor.lambda$executeService$0(CompletionExecutor.java:177)
        at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1395)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373)
        at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182)
        at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655)
        at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622)
        at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165)
Caused by: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: No instances of org.slf4j.simple.SimpleLogger 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=org.slf4j.simple.SimpleLogger.
        at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.classinitialization.ClassInitializationFeature.checkImageHeapInstance(ClassInitializationFeature.java:132)
        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.meta.AnalysisUniverse.replaceObject(AnalysisUniverse.java:595)
        at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.ameta.AnalysisConstantReflectionProvider.replaceObject(AnalysisConstantReflectionProvider.java:177)
        at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.ameta.AnalysisConstantReflectionProvider.interceptValue(AnalysisConstantReflectionProvider.java:148)
        at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.ameta.AnalysisConstantReflectionProvider.readValue(AnalysisConstantReflectionProvider.java:100)
        at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.ameta.AnalysisConstantReflectionProvider.readFieldValue(AnalysisConstantReflectionProvider.java:79)
        at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.util.ConstantFoldUtil$1.readValue(ConstantFoldUtil.java:55)
        at jdk.internal.vm.compiler/org.graalvm.compiler.core.common.spi.JavaConstantFieldProvider.readConstantField(JavaConstantFieldProvider.java:78)
        at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.ameta.AnalysisConstantFieldProvider.readConstantField(AnalysisConstantFieldProvider.java:72)
        at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.util.ConstantFoldUtil.tryConstantFold(ConstantFoldUtil.java:51)
        at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.java.LoadFieldNode.asConstant(LoadFieldNode.java:178)
        at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.java.LoadFieldNode.canonical(LoadFieldNode.java:144)
        at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.java.LoadFieldNode.canonical(LoadFieldNode.java:135)
        at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.java.LoadFieldNode.canonical(LoadFieldNode.java:72)
        at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.spi.Canonicalizable$Unary.canonical(Canonicalizable.java:101)
        at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.SimplifyingGraphDecoder.canonicalizeFixedNode(SimplifyingGraphDecoder.java:214)
        at jdk.internal.vm.compiler/org.graalvm.compiler.replacements.PEGraphDecoder.canonicalizeFixedNode(PEGraphDecoder.java:1572)
        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.phases.InlineBeforeAnalysisGraphDecoder.canonicalizeFixedNode(InlineBeforeAnalysis.java:192)
        at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.SimplifyingGraphDecoder.handleFixedNode(SimplifyingGraphDecoder.java:193)
        at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.GraphDecoder.processNextNode(GraphDecoder.java:821)
        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.phases.InlineBeforeAnalysisGraphDecoder.processNextNode(InlineBeforeAnalysis.java:240)
        at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.GraphDecoder.decode(GraphDecoder.java:548)
        at jdk.internal.vm.compiler/org.graalvm.compiler.replacements.PEGraphDecoder.decode(PEGraphDecoder.java:833)
        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.phases.InlineBeforeAnalysis.decodeGraph(InlineBeforeAnalysis.java:98)
        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlowBuilder.parse(MethodTypeFlowBuilder.java:179)
        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlowBuilder.apply(MethodTypeFlowBuilder.java:349)
        at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlow.createFlowsGraph(MethodTypeFlow.java:93)
        ... 13 more
------------------------------------------------------------------------------------------------------------------------
                        1.6s (3.7% of total time) in 12 GCs | Peak RSS: 0.68GB | CPU load: 1.89
========================================================================================================================
Failed generating 'myapp' after 42.6s.
Error: Image build request failed with exit status 1

I saw there is a similar issue at GitHub, it was closed in 2020, with a comment "Please use a more recent version of Netty, the latest release is recommended. It should contain all the necessary support code for building Native Image." Now is Jan 2023 and I still got the above problem.


Solution

  • I finally cracked the recipe:

    native-image -jar myapp-1.0-jar-with-dependencies.jar myapp  \
     --initialize-at-build-time=org.slf4j.simple.SimpleLogger \
     --initialize-at-build-time=io.netty.util.internal.logging.Slf4JLoggerFactory \
     --initialize-at-build-time=io.netty.channel.MultithreadEventLoopGroup \
     --initialize-at-build-time=io.netty.util.internal.logging.InternalLoggerFactory \
     --initialize-at-build-time=org.slf4j.LoggerFactory \
     --initialize-at-run-time=io.netty.channel.DefaultFileRegion  \
     --initialize-at-run-time=io.netty.channel.epoll.Native  \
     --initialize-at-run-time=io.netty.channel.epoll.Epoll  \
     --initialize-at-run-time=io.netty.channel.epoll.EpollEventLoop  \
     --initialize-at-run-time=io.netty.channel.epoll.EpollEventArray  \
     --initialize-at-run-time=io.netty.channel.kqueue.KQueue  \
     --initialize-at-run-time=io.netty.channel.kqueue.KQueueEventLoop  \
     --initialize-at-run-time=io.netty.channel.kqueue.KQueueEventArray  \
     --initialize-at-run-time=io.netty.channel.kqueue.Native  \
     --initialize-at-run-time=io.netty.channel.unix.Limits  \
     --initialize-at-run-time=io.netty.channel.unix.Errors  \
     --initialize-at-run-time=io.netty.channel.unix.IovArray  \
     --initialize-at-run-time=io.netty.handler.ssl.BouncyCastleAlpnSslUtils  \
     --initialize-at-run-time=io.netty.incubator.codec.quic.InsecureQuicTokenHandler  \
     --initialize-at-run-time=io.netty.incubator.codec.quic.SecureRandomQuicConnectionIdGenerator \
     --report-unsupported-elements-at-runtime \
     -H:+ReportExceptionStackTraces
    

    No secret but keep trying and studying the output and following the suggestions and adjusting. But it's not easy, I tried different combinations of initialize-at-build-time and initialize-at-run-time with all these classes. I think the tool may need to be improved to save this kind of try.

    Right now the jar file is compiled successfully (also thanks to the help from @Karam), but I am still struggling to handle some run-time exceptions prompted out from running the compiled output which never been thrown when running as a jar file.