title: How do you debug a 'No instances of ... are allowed in the image heap' when building a native image?
body: <p>I have a little Java application that implements a RESTful API using Micronaut 2.0.0. Under the hood, it uses Redisson 3.13.1 to go to Redis. Redisson, in turn, uses Netty (4.1.49).</p>
  <p>The application works fine in a 'classic' java (on HotSpot, both Java 8 and 11).</p>
  <p>I'm trying to build a native image out of this application using GraalVM.</p>
  <p>The command is <em>approximately</em> like this:</p>
  <pre><code>native-image --no-server --no-fallback -H:+TraceClassInitialization -H:+PrintClassInitialization --report-unsupported-elements-at-runtime --initialize-at-build-time=reactor.core.publisher.Flux,reactor.core.publisher.Mono -H:ConfigurationFileDirectories=target/config -cp target/app-1.0.0-SNAPSHOT.jar com.app.AppApplication target/app
  </code></pre>
  <p>Here is what I get:</p>
  <pre><code>Error: Unsupported features in 4 methods
  Detailed message:
  Error: No instances of java.net.Inet4Address 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.
  Trace: Object was reached by 
      reading field io.netty.channel.socket.InternetProtocolFamily.localHost of
          constant io.netty.channel.socket.InternetProtocolFamily@593f1f62 reached by 
      scanning method io.netty.resolver.dns.DnsNameResolver.preferredAddressType(DnsNameResolver.java:481)
  Call path from entry point to io.netty.resolver.dns.DnsNameResolver.preferredAddressType(ResolvedAddressTypes): 
      at io.netty.resolver.dns.DnsNameResolver.preferredAddressType(DnsNameResolver.java:478)
      at io.netty.resolver.dns.DnsNameResolver.&lt;init&gt;(DnsNameResolver.java:436)
      at io.netty.resolver.dns.DnsNameResolverBuilder.build(DnsNameResolverBuilder.java:473)
      at io.netty.resolver.dns.DnsAddressResolverGroup.newNameResolver(DnsAddressResolverGroup.java:111)
      at io.netty.resolver.dns.DnsAddressResolverGroup.newResolver(DnsAddressResolverGroup.java:91)
      at io.netty.resolver.dns.DnsAddressResolverGroup.newResolver(DnsAddressResolverGroup.java:76)
      at io.netty.resolver.AddressResolverGroup.getResolver(AddressResolverGroup.java:70)
      at org.redisson.cluster.ClusterConnectionManager$1.run(ClusterConnectionManager.java:251)
      at com.oracle.svm.core.jdk.RuntimeSupport.executeHooks(RuntimeSupport.java:125)
      at com.oracle.svm.core.jdk.RuntimeSupport.executeStartupHooks(RuntimeSupport.java:75)
      at com.oracle.svm.core.JavaMainWrapper.runCore(JavaMainWrapper.java:141)
      at com.oracle.svm.core.JavaMainWrapper.run(JavaMainWrapper.java:184)
      at com.oracle.svm.core.code.IsolateEnterStub.JavaMainWrapper_run_5087f5482cc9a6abc971913ece43acb471d2631b(generated:0)
  </code></pre>
  <p>That's just a part of the output, it also produces similar reports on other 3 errors.</p>
  <p>I'm still struggling to understand the issue, but I suppose that, as <code>java.net.InetAddress</code> has native methods in it, neither it nor its subclass <code>java.net.Inet4Address</code> can be initialized at build time. This means that an instance of <code>Inet4Address</code> cannot be visible for a code that is initialized at build time (at initialization stage, in Java terms). And the native image builder found a way that kinda reaches a point where such an object is visible. It even shows the trace, but the thing is that <code>ClusterConnectionManager$1</code> is a <code>Runnable</code> that is only submitted to an <code>Executor</code> at runtime (waaaay after the static initialization).</p>
  <p>How do you debug such situations? Namely:</p>
  <ol>
  <li>How do you find the culprit?</li>
  <li>How do you fix it when the culprit is found?</li>
  </ol>
  <p>PS. If I add <code>--initialize-at-run-time=java.net.InetAddress</code>, it fails differently:</p>
  <pre><code>Error: The class java.net.InetAddress has already been initialized; it is too late 
  to register java.net.InetAddress for build-time initialization (from the command 
  line). java.net.InetAddress has been initialized without the native-image 
  initialization instrumentation and the stack trace can't be tracked. Try avoiding 
  this conflict by avoiding to initialize the class that caused initialization of 
  java.net.InetAddress or by not marking java.net.InetAddress for build-time 
  initialization.
  </code></pre>
  <p>Java reports itself as <code>build 25.252-b09-jvmci-20.1-b02, mixed mode</code>.</p>
  <p>PPS. I found this <a href="https://stackoverflow.com/questions/59011565/no-instances-of-are-allowed-in-the-image-heap-as-this-class-should-be-initia">No instances of ... are allowed in the image heap as this class should be initialized at image runtime</a> and it seems that the Quarkus issue was fixed. But I still do not understand how to fix the issue at hand. Any help would be appreciated.</p>