From ff2d118341dfc95f34bcf114b005625d2fc930f6 Mon Sep 17 00:00:00 2001 From: Burke Davison <40617934+burkedavison@users.noreply.github.com> Date: Thu, 19 Jan 2023 13:56:49 -0500 Subject: [PATCH] fix: Add native image reflect-config.json to gax-grpc (#1251) * fix: Add native image reflect-config.json to gax-grpc * fix: Place all netty reflect configurations in GrpcNettyFeature.java * fix: format * ci: downstream test graalvm native image compilation on java-kms and java-os-login * fix: register full classes for reflection * fix: format * fix: add java17-required add-opens=java.base config to native-image.properties * fix: change add-opens argument to java.base/java.time --- .kokoro/presubmit/common.cfg | 5 +- .../grpc/nativeimage/GrpcNettyFeature.java | 25 ++ .../gax-grpc/native-image.properties | 3 +- .../gax-grpc/reflect-config.json | 287 ++++++++++++++++++ 4 files changed, 316 insertions(+), 4 deletions(-) create mode 100644 gax-java/gax-grpc/src/main/resources/META-INF/native-image/com.google.api/gax-grpc/reflect-config.json diff --git a/.kokoro/presubmit/common.cfg b/.kokoro/presubmit/common.cfg index d0c5a31d2e..1f21b18ef8 100644 --- a/.kokoro/presubmit/common.cfg +++ b/.kokoro/presubmit/common.cfg @@ -36,7 +36,6 @@ env_vars: { # builds. env_vars: { key: "MODULES_UNDER_TEST" - value: "java-os-login,java-asset" # OS login's ITSystemTest exercises gax-java's native image - # reflect-config.json. - # Asset not required - added only as a sanity check. + value: "java-kms,java-os-login" # KMS's ITKmsTest exercises gax-java's native image + # reflect-config.json. OS Login has a similar issue. } diff --git a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/nativeimage/GrpcNettyFeature.java b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/nativeimage/GrpcNettyFeature.java index c2cf0a28d2..23db568b72 100644 --- a/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/nativeimage/GrpcNettyFeature.java +++ b/gax-java/gax-grpc/src/main/java/com/google/api/gax/grpc/nativeimage/GrpcNettyFeature.java @@ -78,6 +78,13 @@ private static void loadGrpcNettyClasses(BeforeAnalysisAccess access) { registerClassForReflection(access, "io.grpc.netty.shaded.io.netty.util.ReferenceCountUtil"); registerClassForReflection( access, "io.grpc.netty.shaded.io.netty.buffer.AbstractByteBufAllocator"); + registerForUnsafeFieldAccess( + access, "io.grpc.netty.shaded.io.netty.buffer.AbstractReferenceCountedByteBuf", "refCnt"); + registerForUnsafeFieldAccess( + access, "io.grpc.netty.shaded.io.netty.util.AbstractReferenceCounted", "refCnt"); + registerClassForReflection(access, "io.grpc.netty.shaded.io.netty.channel.DefaultFileRegion"); + registerClassForReflection( + access, "io.grpc.netty.shaded.io.netty.channel.unix.PeerCredentials"); // Epoll Libraries registerClassForReflection(access, "io.grpc.netty.shaded.io.netty.channel.epoll.Epoll"); @@ -89,6 +96,24 @@ private static void loadGrpcNettyClasses(BeforeAnalysisAccess access) { access, "io.grpc.netty.shaded.io.netty.channel.epoll.EpollServerSocketChannel"); registerForReflectiveInstantiation( access, "io.grpc.netty.shaded.io.netty.channel.epoll.EpollSocketChannel"); + registerClassForReflection( + access, + "io.grpc.netty.shaded.io.netty.channel.epoll.NativeDatagramPacketArray$NativeDatagramPacket"); + + // tcnative + registerClassForReflection( + access, "io.grpc.netty.shaded.io.netty.internal.tcnative.CertificateCallback"); + registerClassForReflection( + access, "io.grpc.netty.shaded.io.netty.internal.tcnative.CertificateCallbackTask"); + registerClassForReflection( + access, "io.grpc.netty.shaded.io.netty.internal.tcnative.SSLContext"); + registerClassForReflection( + access, "io.grpc.netty.shaded.io.netty.internal.tcnative.SSLPrivateKeyMethodDecryptTask"); + registerClassForReflection( + access, "io.grpc.netty.shaded.io.netty.internal.tcnative.SSLPrivateKeyMethodSignTask"); + registerClassForReflection( + access, "io.grpc.netty.shaded.io.netty.internal.tcnative.SSLPrivateKeyMethodTask"); + registerClassForReflection(access, "io.grpc.netty.shaded.io.netty.internal.tcnative.SSLTask"); // Unsafe field accesses registerForUnsafeFieldAccess( diff --git a/gax-java/gax-grpc/src/main/resources/META-INF/native-image/com.google.api/gax-grpc/native-image.properties b/gax-java/gax-grpc/src/main/resources/META-INF/native-image/com.google.api/gax-grpc/native-image.properties index f8c0ada537..b66e70603f 100644 --- a/gax-java/gax-grpc/src/main/resources/META-INF/native-image/com.google.api/gax-grpc/native-image.properties +++ b/gax-java/gax-grpc/src/main/resources/META-INF/native-image/com.google.api/gax-grpc/native-image.properties @@ -1,4 +1,5 @@ -Args = --initialize-at-run-time=io.grpc.netty.shaded.io.netty.handler.ssl.OpenSsl,\ +Args=--add-opens=java.base/java.time=ALL-UNNAMED \ + --initialize-at-run-time=io.grpc.netty.shaded.io.netty.handler.ssl.OpenSsl,\ io.grpc.netty.shaded.io.netty.internal.tcnative.SSL,\ io.grpc.netty.shaded.io.netty.internal.tcnative.CertificateVerifier,\ io.grpc.netty.shaded.io.netty.internal.tcnative.SSLPrivateKeyMethod,\ diff --git a/gax-java/gax-grpc/src/main/resources/META-INF/native-image/com.google.api/gax-grpc/reflect-config.json b/gax-java/gax-grpc/src/main/resources/META-INF/native-image/com.google.api/gax-grpc/reflect-config.json new file mode 100644 index 0000000000..69f24071df --- /dev/null +++ b/gax-java/gax-grpc/src/main/resources/META-INF/native-image/com.google.api/gax-grpc/reflect-config.json @@ -0,0 +1,287 @@ +[ + { + "name": "[B" + }, + { + "name": "com.google.auth.Credentials", + "allDeclaredFields": true + }, + { + "name": "com.google.auth.appengine.AppEngineCredentials" + }, + { + "name": "com.google.auth.oauth2.AccessToken", + "allDeclaredFields": true + }, + { + "name": "com.google.auth.oauth2.GoogleCredentials", + "allDeclaredFields": true, + "methods": [ + { + "name": "getQuotaProjectId", + "parameterTypes": [] + } + ] + }, + { + "name": "com.google.auth.oauth2.OAuth2Credentials", + "allDeclaredFields": true + }, + { + "name": "com.google.auth.oauth2.OAuth2Credentials$OAuthValue", + "allDeclaredFields": true + }, + { + "name": "com.google.auth.oauth2.UserCredentials", + "allDeclaredFields": true + }, + { + "name": "com.google.protobuf.ExtensionRegistry", + "methods": [ + { + "name": "getEmptyRegistry", + "parameterTypes": [] + } + ] + }, + { + "name": "com.sun.crypto.provider.TlsMasterSecretGenerator", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "com.sun.jndi.dns.DnsContextFactory" + }, + { + "name": "io.grpc.internal.DnsNameResolverProvider" + }, + { + "name": "io.grpc.internal.JndiResourceResolverFactory", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "io.grpc.internal.PickFirstLoadBalancerProvider" + }, + { + "name": "io.grpc.util.SecretRoundRobinLoadBalancerProvider$Provider", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "java.io.FileDescriptor" + }, + { + "name": "java.lang.Exception" + }, + { + "name": "java.lang.IllegalArgumentException" + }, + { + "name": "java.lang.NullPointerException" + }, + { + "name": "java.lang.Object", + "allDeclaredFields": true, + "queryAllDeclaredMethods": true + }, + { + "name": "java.lang.OutOfMemoryError" + }, + { + "name": "java.lang.String" + }, + { + "name": "java.lang.Throwable", + "methods": [ + { + "name": "addSuppressed", + "parameterTypes": [ + "java.lang.Throwable" + ] + } + ] + }, + { + "name": "java.nio.Bits", + "fields": [ + { + "name": "UNALIGNED" + } + ] + }, + { + "name": "java.nio.Buffer", + "fields": [ + { + "name": "address" + } + ] + }, + { + "name": "java.nio.ByteBuffer", + "methods": [ + { + "name": "alignedSlice", + "parameterTypes": [ + "int" + ] + } + ] + }, + { + "name": "java.nio.DirectByteBuffer", + "methods": [ + { + "name": "", + "parameterTypes": [ + "long", + "int" + ] + } + ] + }, + { + "name": "java.nio.channels.FileChannel" + }, + { + "name": "java.security.AlgorithmParametersSpi" + }, + { + "name": "java.security.KeyStoreSpi" + }, + { + "name": "java.security.MessageDigestSpi" + }, + { + "name": "java.security.SecureRandomParameters" + }, + { + "name": "java.sql.Date" + }, + { + "name": "java.time.Duration", + "allDeclaredFields": true + }, + { + "name": "java.util.AbstractMap", + "allDeclaredFields": true + }, + { + "name": "java.util.concurrent.atomic.LongAdder", + "queryAllPublicConstructors": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + }, + { + "name": "add", + "parameterTypes": [ + "long" + ] + }, + { + "name": "sum", + "parameterTypes": [] + } + ] + }, + { + "name": "javax.naming.directory.InitialDirContext" + }, + { + "name": "javax.security.auth.x500.X500Principal", + "fields": [ + { + "name": "thisX500Name" + } + ], + "methods": [ + { + "name": "", + "parameterTypes": [ + "sun.security.x509.X500Name" + ] + } + ] + }, + { + "name": "jdk.internal.misc.Unsafe", + "methods": [ + { + "name": "getUnsafe", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.misc.Unsafe", + "fields": [ + { + "name": "theUnsafe" + } + ], + "methods": [ + { + "name": "copyMemory", + "parameterTypes": [ + "java.lang.Object", + "long", + "java.lang.Object", + "long", + "long" + ] + }, + { + "name": "getAndAddLong", + "parameterTypes": [ + "java.lang.Object", + "long", + "long" + ] + }, + { + "name": "getAndSetObject", + "parameterTypes": [ + "java.lang.Object", + "long", + "java.lang.Object" + ] + }, + { + "name": "invokeCleaner", + "parameterTypes": [ + "java.nio.ByteBuffer" + ] + }, + { + "name": "storeFence", + "parameterTypes": [] + } + ] + }, + { + "name": "sun.nio.ch.SelectorImpl", + "fields": [ + { + "name": "publicSelectedKeys" + }, + { + "name": "selectedKeys" + } + ] + } +]