From 7dec2382a0e362bdab5c5c175509cab189acf700 Mon Sep 17 00:00:00 2001 From: Violeta Georgieva Date: Tue, 30 May 2023 12:36:17 +0300 Subject: [PATCH] Add native-image support (#510) Motivation: In order to support `native-image`, the project has to provide the corresponding configuration for reflection, JNI and resources. Modifications: - Module `codec-native-quic`: Add profile `native-image-agent` for generating `native-image` configuration - New module `testsuite-native-image`: Add profiles `native-image-quic-server`/`native-image-quic-client` for testing the `native-image` configuration Result: Fixes #464 --- codec-native-quic/pom.xml | 83 +++ .../jni-config.json | 117 +++++ .../reflect-config.json | 490 ++++++++++++++++++ .../resource-config.json | 27 + .../src/test/resources/netty-filter.json | 6 + .../src/test/resources/test-class-filter.json | 12 + pom.xml | 4 +- testsuite-native-image/pom.xml | 204 ++++++++ 8 files changed, 942 insertions(+), 1 deletion(-) create mode 100644 codec-native-quic/src/main/resources/META-INF/native-image/io.netty.incubator/netty-incubator-codec-native-quic/jni-config.json create mode 100644 codec-native-quic/src/main/resources/META-INF/native-image/io.netty.incubator/netty-incubator-codec-native-quic/reflect-config.json create mode 100644 codec-native-quic/src/main/resources/META-INF/native-image/io.netty.incubator/netty-incubator-codec-native-quic/resource-config.json create mode 100644 codec-native-quic/src/test/resources/netty-filter.json create mode 100644 codec-native-quic/src/test/resources/test-class-filter.json create mode 100644 testsuite-native-image/pom.xml diff --git a/codec-native-quic/pom.xml b/codec-native-quic/pom.xml index a6bc629aa..82c0c3b9d 100644 --- a/codec-native-quic/pom.xml +++ b/codec-native-quic/pom.xml @@ -494,6 +494,89 @@ -Dio.netty.leakDetectionLevel=paranoid -Dio.netty.leakDetection.targetRecords=32 + + + + + native-image-agent + + + org.bouncycastle + bcpkix-jdk15on + + + + + + maven-compiler-plugin + + 17 + 17 + + + + maven-surefire-plugin + + + io.netty.incubator.codec.quic.QuicChannelEchoTest + + + + + org.graalvm.buildtools + native-maven-plugin + ${native.maven.plugin.version} + + + org.codehaus.plexus + plexus-utils + 3.4.2 + + + true + + + test-native + + test + + test + + + + true + + true + + + true + Conditional + + + ${project.basedir}/src/test/resources/netty-filter.json + ${project.basedir}/src/test/resources/test-class-filter.json + true + + + + true + true + false + false + true + + + + main + + true + + + + + + + diff --git a/codec-native-quic/src/main/resources/META-INF/native-image/io.netty.incubator/netty-incubator-codec-native-quic/jni-config.json b/codec-native-quic/src/main/resources/META-INF/native-image/io.netty.incubator/netty-incubator-codec-native-quic/jni-config.json new file mode 100644 index 000000000..0e40f871d --- /dev/null +++ b/codec-native-quic/src/main/resources/META-INF/native-image/io.netty.incubator/netty-incubator-codec-native-quic/jni-config.json @@ -0,0 +1,117 @@ +[ +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"[B" +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"[Ljava.lang.Object;" +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"[Ljava.lang.String;" +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"[[B" +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"io.netty.incubator.codec.quic.BoringSSL" +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"io.netty.incubator.codec.quic.BoringSSLCertificateCallbackTask", + "fields":[ + {"name":"chain"}, + {"name":"key"} + ], + "methods":[{"name":"","parameterTypes":["long","byte[]","byte[][]","java.lang.String[]","io.netty.incubator.codec.quic.BoringSSLCertificateCallback"] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"io.netty.incubator.codec.quic.BoringSSLCertificateVerifyCallbackTask", + "methods":[{"name":"","parameterTypes":["long","byte[][]","java.lang.String","io.netty.incubator.codec.quic.BoringSSLCertificateVerifyCallback"] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"io.netty.incubator.codec.quic.BoringSSLHandshakeCompleteCallback", + "methods":[{"name":"handshakeComplete","parameterTypes":["long","byte[]","java.lang.String","java.lang.String","byte[]","byte[][]","long","long","byte[]","boolean"] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"io.netty.incubator.codec.quic.BoringSSLKeylogCallback", + "methods":[{"name":"logKey","parameterTypes":["long","java.lang.String"] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"io.netty.incubator.codec.quic.BoringSSLNativeStaticallyReferencedJniMethods" +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"io.netty.incubator.codec.quic.BoringSSLPrivateKeyMethodDecryptTask", + "methods":[{"name":"","parameterTypes":["long","byte[]","io.netty.incubator.codec.quic.BoringSSLPrivateKeyMethod"] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"io.netty.incubator.codec.quic.BoringSSLPrivateKeyMethodSignTask", + "methods":[{"name":"","parameterTypes":["long","int","byte[]","io.netty.incubator.codec.quic.BoringSSLPrivateKeyMethod"] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"io.netty.incubator.codec.quic.BoringSSLPrivateKeyMethodTask", + "fields":[{"name":"resultBytes"}] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"io.netty.incubator.codec.quic.BoringSSLSessionCallback", + "methods":[{"name":"newSession","parameterTypes":["long","long","long","byte[]","boolean","byte[]"] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"io.netty.incubator.codec.quic.BoringSSLTask", + "fields":[ + {"name":"complete"}, + {"name":"returnValue"} + ] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"io.netty.incubator.codec.quic.BoringSSLTlsextServernameCallback", + "methods":[{"name":"selectCtx","parameterTypes":["long","java.lang.String"] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"io.netty.incubator.codec.quic.Quiche" +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"io.netty.incubator.codec.quic.QuicheLogger", + "methods":[{"name":"log","parameterTypes":["java.lang.String"] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"io.netty.incubator.codec.quic.QuicheNativeStaticallyReferencedJniMethods" +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"java.lang.Boolean", + "methods":[ + {"name":"getBoolean","parameterTypes":["java.lang.String"] }, + {"name":"valueOf","parameterTypes":["boolean"] } + ] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"java.lang.Integer", + "methods":[{"name":"","parameterTypes":["int"] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"java.lang.Object" +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"java.lang.String" +} +] diff --git a/codec-native-quic/src/main/resources/META-INF/native-image/io.netty.incubator/netty-incubator-codec-native-quic/reflect-config.json b/codec-native-quic/src/main/resources/META-INF/native-image/io.netty.incubator/netty-incubator-codec-native-quic/reflect-config.json new file mode 100644 index 000000000..f9d097d61 --- /dev/null +++ b/codec-native-quic/src/main/resources/META-INF/native-image/io.netty.incubator/netty-incubator-codec-native-quic/reflect-config.json @@ -0,0 +1,490 @@ +[ +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"[B" +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.HmacSignQuicConnectionIdGenerator"}, + "name":"com.sun.crypto.provider.HmacCore$HmacSHA256", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicSslContextBuilder"}, + "name":"com.sun.crypto.provider.HmacCore$HmacSHA256", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicSslContextBuilder"}, + "name":"com.sun.crypto.provider.PBEKeyFactory$PBEWithMD5AndDES", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicSslContextBuilder"}, + "name":"com.sun.crypto.provider.PBES2Core$HmacSHA256AndAES_256", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicSslContextBuilder"}, + "name":"com.sun.crypto.provider.PBES2Parameters$General", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicSslContextBuilder"}, + "name":"com.sun.crypto.provider.PBES2Parameters$HmacSHA256AndAES_256", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicConnectionAddress"}, + "name":"io.netty.buffer.AbstractByteBufAllocator", + "queryAllDeclaredMethods":true +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicConnectionAddress"}, + "name":"io.netty.buffer.AbstractReferenceCountedByteBuf", + "fields":[{"name":"refCnt"}] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quic"}, + "name":"io.netty.channel.ChannelInboundHandlerAdapter", + "methods":[ + {"name":"channelReadComplete","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"channelWritabilityChanged","parameterTypes":["io.netty.channel.ChannelHandlerContext"] } + ] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicStreamChannelBootstrap$QuicStreamChannelBootstrapHandler"}, + "name":"io.netty.channel.ChannelInboundHandlerAdapter", + "methods":[ + {"name":"channelActive","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"channelInactive","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"channelRead","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Object"] }, + {"name":"channelUnregistered","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"exceptionCaught","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Throwable"] }, + {"name":"userEventTriggered","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Object"] } + ] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicheQuicChannel"}, + "name":"io.netty.channel.ChannelInboundHandlerAdapter", + "methods":[{"name":"channelActive","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicheQuicChannel$2"}, + "name":"io.netty.channel.ChannelInboundHandlerAdapter", + "methods":[ + {"name":"channelActive","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"channelInactive","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"channelRead","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Object"] }, + {"name":"channelRegistered","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"channelUnregistered","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"exceptionCaught","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Throwable"] } + ] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicheQuicChannel$QuicChannelUnsafe"}, + "name":"io.netty.channel.ChannelInboundHandlerAdapter", + "methods":[ + {"name":"channelInactive","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"channelRead","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Object"] }, + {"name":"channelReadComplete","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"channelRegistered","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"channelUnregistered","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"channelWritabilityChanged","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"exceptionCaught","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Throwable"] }, + {"name":"userEventTriggered","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Object"] } + ] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicheQuicServerCodec"}, + "name":"io.netty.channel.ChannelInboundHandlerAdapter", + "methods":[ + {"name":"channelActive","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"channelInactive","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"channelRead","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Object"] }, + {"name":"channelRegistered","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"channelUnregistered","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"exceptionCaught","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Throwable"] }, + {"name":"userEventTriggered","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Object"] } + ] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicheQuicChannel"}, + "name":"io.netty.channel.ChannelInitializer", + "methods":[ + {"name":"channelRegistered","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"exceptionCaught","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Throwable"] } + ] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicheQuicChannel$2"}, + "name":"io.netty.channel.DefaultChannelPipeline$HeadContext", + "methods":[ + {"name":"bind","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.net.SocketAddress","io.netty.channel.ChannelPromise"] }, + {"name":"channelActive","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"channelInactive","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"channelRead","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Object"] }, + {"name":"channelReadComplete","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"channelRegistered","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"channelUnregistered","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"channelWritabilityChanged","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"close","parameterTypes":["io.netty.channel.ChannelHandlerContext","io.netty.channel.ChannelPromise"] }, + {"name":"connect","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.net.SocketAddress","java.net.SocketAddress","io.netty.channel.ChannelPromise"] }, + {"name":"deregister","parameterTypes":["io.netty.channel.ChannelHandlerContext","io.netty.channel.ChannelPromise"] }, + {"name":"disconnect","parameterTypes":["io.netty.channel.ChannelHandlerContext","io.netty.channel.ChannelPromise"] }, + {"name":"exceptionCaught","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Throwable"] }, + {"name":"flush","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"read","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"userEventTriggered","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Object"] }, + {"name":"write","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Object","io.netty.channel.ChannelPromise"] } + ] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicheQuicStreamChannel$1"}, + "name":"io.netty.channel.DefaultChannelPipeline$HeadContext", + "methods":[ + {"name":"bind","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.net.SocketAddress","io.netty.channel.ChannelPromise"] }, + {"name":"channelActive","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"channelInactive","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"channelRead","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Object"] }, + {"name":"channelReadComplete","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"channelRegistered","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"channelUnregistered","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"channelWritabilityChanged","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"close","parameterTypes":["io.netty.channel.ChannelHandlerContext","io.netty.channel.ChannelPromise"] }, + {"name":"connect","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.net.SocketAddress","java.net.SocketAddress","io.netty.channel.ChannelPromise"] }, + {"name":"deregister","parameterTypes":["io.netty.channel.ChannelHandlerContext","io.netty.channel.ChannelPromise"] }, + {"name":"disconnect","parameterTypes":["io.netty.channel.ChannelHandlerContext","io.netty.channel.ChannelPromise"] }, + {"name":"exceptionCaught","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Throwable"] }, + {"name":"flush","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"read","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"userEventTriggered","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Object"] }, + {"name":"write","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Object","io.netty.channel.ChannelPromise"] } + ] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicheQuicChannel$2"}, + "name":"io.netty.channel.DefaultChannelPipeline$TailContext", + "methods":[ + {"name":"channelActive","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"channelInactive","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"channelRead","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Object"] }, + {"name":"channelReadComplete","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"channelRegistered","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"channelUnregistered","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"channelWritabilityChanged","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"exceptionCaught","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Throwable"] }, + {"name":"userEventTriggered","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Object"] } + ] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicheQuicStreamChannel$1"}, + "name":"io.netty.channel.DefaultChannelPipeline$TailContext", + "methods":[ + {"name":"channelActive","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"channelInactive","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"channelRead","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Object"] }, + {"name":"channelReadComplete","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"channelRegistered","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"channelUnregistered","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"channelWritabilityChanged","parameterTypes":["io.netty.channel.ChannelHandlerContext"] }, + {"name":"exceptionCaught","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Throwable"] }, + {"name":"userEventTriggered","parameterTypes":["io.netty.channel.ChannelHandlerContext","java.lang.Object"] } + ] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"io.netty.incubator.codec.quic.BoringSSLCertificateCallback" +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"io.netty.incubator.codec.quic.BoringSSLCertificateVerifyCallback" +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"io.netty.incubator.codec.quic.BoringSSLHandshakeCompleteCallback" +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicheQuicChannel"}, + "name":"io.netty.incubator.codec.quic.QuicStreamChannelBootstrap$QuicStreamChannelBootstrapHandler" +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"io.netty.incubator.codec.quic.QuicheLogger" +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicheQuicChannel"}, + "name":"io.netty.util.ReferenceCountUtil", + "queryAllDeclaredMethods":true +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"io.netty.util.internal.NativeLibraryUtil", + "methods":[{"name":"loadLibrary","parameterTypes":["java.lang.String","boolean"] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicheQuicChannel"}, + "name":"io.netty.util.internal.shaded.org.jctools.queues.MpscArrayQueueConsumerIndexField", + "fields":[{"name":"consumerIndex"}] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicheQuicChannel"}, + "name":"io.netty.util.internal.shaded.org.jctools.queues.MpscArrayQueueProducerIndexField", + "fields":[{"name":"producerIndex"}] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicheQuicChannel"}, + "name":"io.netty.util.internal.shaded.org.jctools.queues.MpscArrayQueueProducerLimitField", + "fields":[{"name":"producerLimit"}] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"java.io.FilePermission" +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"java.lang.RuntimePermission" +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"java.lang.String" +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"java.lang.management.ManagementFactory", + "methods":[{"name":"getRuntimeMXBean","parameterTypes":[] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"java.lang.management.RuntimeMXBean", + "methods":[{"name":"getInputArguments","parameterTypes":[] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"java.net.NetPermission" +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"java.net.SocketPermission" +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"java.net.URLPermission", + "methods":[{"name":"","parameterTypes":["java.lang.String","java.lang.String"] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"java.nio.Bits", + "methods":[{"name":"unaligned","parameterTypes":[] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"java.nio.Buffer", + "fields":[{"name":"address"}] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"java.nio.ByteBuffer", + "methods":[{"name":"alignedSlice","parameterTypes":["int"] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"java.nio.DirectByteBuffer", + "methods":[{"name":"","parameterTypes":["long","int"] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"java.security.AllPermission" +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.HmacSignQuicConnectionIdGenerator"}, + "name":"java.security.SecureRandomParameters" +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicSslContextBuilder"}, + "name":"java.security.SecureRandomParameters" +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"java.security.SecureRandomParameters" +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.SecureRandomQuicConnectionIdGenerator"}, + "name":"java.security.SecureRandomParameters" +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"java.security.SecurityPermission" +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"java.util.PropertyPermission" +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"javax.management.ObjectName" +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.BoringSSLCertificateVerifyCallback"}, + "name":"javax.net.ssl.X509ExtendedTrustManager" +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.BoringSSL"}, + "name":"javax.security.auth.x500.X500Principal", + "methods":[{"name":"","parameterTypes":["sun.security.x509.X500Name"] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"jdk.internal.misc.Unsafe", + "methods":[{"name":"getUnsafe","parameterTypes":[] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicheQuicSslContext"}, + "name":"org.bouncycastle.jcajce.provider.asymmetric.rsa.KeyFactorySpi", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicHeaderParser"}, + "name":"sun.misc.Unsafe", + "methods":[{"name":"invokeCleaner","parameterTypes":["java.nio.ByteBuffer"] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicSslContext"}, + "name":"sun.misc.Unsafe", + "methods":[{"name":"invokeCleaner","parameterTypes":["java.nio.ByteBuffer"] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"sun.misc.Unsafe", + "fields":[{"name":"theUnsafe"}], + "methods":[ + {"name":"copyMemory","parameterTypes":["java.lang.Object","long","java.lang.Object","long","long"] }, + {"name":"invokeCleaner","parameterTypes":["java.nio.ByteBuffer"] }, + {"name":"storeFence","parameterTypes":[] } + ] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicheQuicCodec"}, + "name":"sun.misc.Unsafe", + "methods":[{"name":"invokeCleaner","parameterTypes":["java.nio.ByteBuffer"] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicheQuicConnection"}, + "name":"sun.misc.Unsafe", + "methods":[{"name":"invokeCleaner","parameterTypes":["java.nio.ByteBuffer"] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicheQuicServerCodec"}, + "name":"sun.misc.Unsafe", + "methods":[{"name":"invokeCleaner","parameterTypes":["java.nio.ByteBuffer"] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicheQuicSslContext"}, + "name":"sun.misc.Unsafe", + "methods":[{"name":"invokeCleaner","parameterTypes":["java.nio.ByteBuffer"] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicheQuicStreamChannel$QuicStreamChannelUnsafe"}, + "name":"sun.misc.Unsafe", + "methods":[{"name":"invokeCleaner","parameterTypes":["java.nio.ByteBuffer"] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicSslContextBuilder"}, + "name":"sun.security.pkcs12.PKCS12KeyStore", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicheQuicSslContext"}, + "name":"sun.security.pkcs12.PKCS12KeyStore", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicSslContextBuilder"}, + "name":"sun.security.pkcs12.PKCS12KeyStore$DualFormatPKCS12", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicheQuicSslContext"}, + "name":"sun.security.pkcs12.PKCS12KeyStore$DualFormatPKCS12", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.HmacSignQuicConnectionIdGenerator"}, + "name":"sun.security.provider.NativePRNG", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicSslContextBuilder"}, + "name":"sun.security.provider.NativePRNG", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"sun.security.provider.NativePRNG", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.SecureRandomQuicConnectionIdGenerator"}, + "name":"sun.security.provider.NativePRNG", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "name":"sun.security.provider.SHA", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.HmacSignQuicConnectionIdGenerator"}, + "name":"sun.security.provider.SHA2$SHA256", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicSslContextBuilder"}, + "name":"sun.security.provider.SHA2$SHA256", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.BoringSSL"}, + "name":"sun.security.provider.X509Factory", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.BoringSSLCertificateVerifyCallback"}, + "name":"sun.security.provider.X509Factory", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicSslContext"}, + "name":"sun.security.provider.X509Factory", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicheQuicSslContext"}, + "name":"sun.security.provider.X509Factory", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicSslContextBuilder"}, + "name":"sun.security.rsa.RSAKeyFactory$Legacy", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.BoringSSLKeylessManagerFactory"}, + "name":"sun.security.ssl.KeyManagerFactoryImpl$SunX509", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicSslContextBuilder"}, + "name":"sun.security.ssl.KeyManagerFactoryImpl$SunX509", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "condition":{"typeReachable":"io.netty.incubator.codec.quic.QuicheQuicSslContext"}, + "name":"sun.security.ssl.TrustManagerFactoryImpl$PKIXFactory", + "methods":[{"name":"","parameterTypes":[] }] +} +] diff --git a/codec-native-quic/src/main/resources/META-INF/native-image/io.netty.incubator/netty-incubator-codec-native-quic/resource-config.json b/codec-native-quic/src/main/resources/META-INF/native-image/io.netty.incubator/netty-incubator-codec-native-quic/resource-config.json new file mode 100644 index 000000000..5eda18838 --- /dev/null +++ b/codec-native-quic/src/main/resources/META-INF/native-image/io.netty.incubator/netty-incubator-codec-native-quic/resource-config.json @@ -0,0 +1,27 @@ +{ + "resources":{ + "includes":[ + { + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "pattern":"\\QMETA-INF/native/libnetty_quiche_osx_x86_64.jnilib\\E" + }, + { + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "pattern":"\\QMETA-INF/native/libnetty_quiche_osx_aarch_64.jnilib\\E", + "//note": "Apple M1 is still not supported https://github.com/oracle/graal/issues/2666" + }, + { + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "pattern":"\\QMETA-INF/native/libnetty_quiche_linux_x86_64.so\\E" + }, + { + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "pattern":"\\QMETA-INF/native/libnetty_quiche_linux_aarch_64.so\\E" + }, + { + "condition":{"typeReachable":"io.netty.incubator.codec.quic.Quiche"}, + "pattern":"\\QMETA-INF/native/netty_quiche_windows_x86_64.dll\\E" + } + ]}, + "bundles":[] +} diff --git a/codec-native-quic/src/test/resources/netty-filter.json b/codec-native-quic/src/test/resources/netty-filter.json new file mode 100644 index 000000000..d90f52938 --- /dev/null +++ b/codec-native-quic/src/test/resources/netty-filter.json @@ -0,0 +1,6 @@ +{ + "rules": [ + {"excludeClasses": "**"}, + {"includeClasses": "io.netty.incubator.codec.quic.**"} + ] +} diff --git a/codec-native-quic/src/test/resources/test-class-filter.json b/codec-native-quic/src/test/resources/test-class-filter.json new file mode 100644 index 000000000..66c7f3671 --- /dev/null +++ b/codec-native-quic/src/test/resources/test-class-filter.json @@ -0,0 +1,12 @@ +{ + "rules": [ + {"includeClasses": "**"}, + {"excludeClasses": "ch.qos.logback.**"}, + {"excludeClasses": "io.netty.incubator.codec.quic.NoValidationQuicTokenHandler"}, + {"excludeClasses": "io.netty.incubator.codec.quic.QuicChannelValidationHandler"}, + {"excludeClasses": "org.apache.maven.surefire.**"} + ], + "regexRules": [ + {"excludeClasses": ".*Test.*"} + ] +} diff --git a/pom.xml b/pom.xml index 806bc68ba..3bdf02d7c 100644 --- a/pom.xml +++ b/pom.xml @@ -68,6 +68,7 @@ codec-classes-quic codec-native-quic + testsuite-native-image @@ -77,6 +78,7 @@ 31 1.15 5.9.0 + 0.9.22 -D_ @@ -443,7 +445,7 @@ org.bouncycastle bcpkix-jdk15on - 1.68 + 1.70 test diff --git a/testsuite-native-image/pom.xml b/testsuite-native-image/pom.xml new file mode 100644 index 000000000..8c8b53dfb --- /dev/null +++ b/testsuite-native-image/pom.xml @@ -0,0 +1,204 @@ + + + + 4.0.0 + + io.netty.incubator + netty-incubator-codec-parent-quic + 0.0.44.Final-SNAPSHOT + + + netty-incubator-codec-quic-testsuite-native-image + ${packaging.type} + Netty/Testsuite/NativeImage + + + + + native-image-quic-server + + + ${project.groupId} + netty-incubator-codec-native-quic + ${project.version} + ${os.detected.classifier} + + + org.bouncycastle + bcpkix-jdk15on + runtime + + + + + + maven-compiler-plugin + + 17 + 17 + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + generate-sources + + add-source + + + + ${project.basedir}/../codec-native-quic/src/test/java/io/netty/incubator/codec/quic/example/ + + + + + + + + org.graalvm.buildtools + native-maven-plugin + ${native.maven.plugin.version} + true + + + build-native + + compile-no-fork + + package + + + + io.netty.incubator.codec.quic.example.QuicServerExample + native-image-quic-server + + true + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.6.0 + + + verify-native-image + verify + + exec + + + + + ${project.build.directory}/native-image-quic-server + + + + + + + native-image-quic-client + + + ${project.groupId} + netty-incubator-codec-native-quic + ${project.version} + ${os.detected.classifier} + + + org.bouncycastle + bcpkix-jdk15on + runtime + + + + + + maven-compiler-plugin + + 17 + 17 + + + + + org.codehaus.mojo + build-helper-maven-plugin + + + generate-sources + + add-source + + + + ${project.basedir}/../codec-native-quic/src/test/java/io/netty/incubator/codec/quic/example/ + + + + + + + + org.graalvm.buildtools + native-maven-plugin + ${native.maven.plugin.version} + true + + + build-native + + compile-no-fork + + package + + + + io.netty.incubator.codec.quic.example.QuicClientExample + native-image-quic-client + + true + + + + + + org.codehaus.mojo + exec-maven-plugin + 1.6.0 + + + verify-native-image + verify + + exec + + + + + ${project.build.directory}/native-image-quic-client + + + + + + +