8

Micronaut 2.0.0 を使用して RESTful API を実装する小さな Java アプリケーションがあります。内部では、Redisson 3.13.1 を使用して Redis にアクセスします。次に、Redisson は Netty (4.1.49) を使用します。

アプリケーションは、「クラシック」Java (HotSpot、Java 8 と 11 の両方) で正常に動作します。

GraalVM を使用して、このアプリケーションからネイティブ イメージを構築しようとしています。

コマンドはおおよそ次のようになります。

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

ここに私が得るものがあります:

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.<init>(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)

これは出力の一部にすぎません。他の 3 つのエラーについても同様のレポートが生成されます。

私はまだ問題を理解するのに苦労していますが、ネイティブメソッドが含まれているため、ビルド時にjava.net.InetAddressそれもそのサブクラスも初期化できないと思います。java.net.Inet4Addressこれは、Inet4Addressビルド時 (Java 用語では初期化段階) に初期化されるコードに対して のインスタンスを表示できないことを意味します。そして、ネイティブの画像ビルダーは、そのようなオブジェクトが見えるようになる方法を見つけました。トレースも表示されますがClusterConnectionManager$1Runnableそれは実行時にのみ送信される ですExecutor(静的な初期化の後に waaay)。

このような状況をどのようにデバッグしますか? すなわち:

  1. どうやって犯人を見つけますか?
  2. 犯人が見つかったらどうやって直すの?

PS。を追加する--initialize-at-run-time=java.net.InetAddressと、別の方法で失敗します。

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.

Java は自身を として報告しますbuild 25.252-b09-jvmci-20.1-b02, mixed mode

PPS。このクラスはイメージの実行時に初期化する必要があるため、イメージ ヒープで ... のインスタンスが許可されていないことがわかり、Quarkus の問題が修正されたようです。しかし、当面の問題を解決する方法はまだわかりません。どんな助けでも大歓迎です。

4

1 に答える 1