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$1
、Runnable
それは実行時にのみ送信される ですExecutor
(静的な初期化の後に waaay)。
このような状況をどのようにデバッグしますか? すなわち:
- どうやって犯人を見つけますか?
- 犯人が見つかったらどうやって直すの?
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 の問題が修正されたようです。しかし、当面の問題を解決する方法はまだわかりません。どんな助けでも大歓迎です。