From a2e61f8f6408f847f377235a618d8e23d8ea98aa Mon Sep 17 00:00:00 2001 From: dzou Date: Mon, 29 Nov 2021 18:31:07 -0500 Subject: [PATCH 1/8] add native image support for core --- google-cloud-core-bom/pom.xml | 5 + google-cloud-core-native-support/pom.xml | 36 ++++ .../features/GoogleJsonClientFeature.java | 113 ++++++++++ .../features/GrpcNettyFeature.java | 132 ++++++++++++ .../features/NativeImageUtils.java | 194 ++++++++++++++++++ .../features/ProtobufMessageFeature.java | 109 ++++++++++ .../clients/CloudFunctionsFeature.java | 149 ++++++++++++++ .../features/clients/CloudSqlFeature.java | 104 ++++++++++ .../features/clients/OpenCensusFeature.java | 43 ++++ .../features/clients/SpannerFeature.java | 52 +++++ .../ApiClientVersionSubstitutions.java | 68 ++++++ .../GaxPropertiesSubstitutions.java | 58 ++++++ ...ttyInternalLoggerFactorySubstitutions.java | 56 +++++ .../google-cloud-core/native-image.properties | 14 ++ .../google-cloud-core/resource-config.json | 13 ++ pom.xml | 15 ++ 16 files changed, 1161 insertions(+) create mode 100644 google-cloud-core-native-support/pom.xml create mode 100644 google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/GoogleJsonClientFeature.java create mode 100644 google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/GrpcNettyFeature.java create mode 100644 google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/NativeImageUtils.java create mode 100644 google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/ProtobufMessageFeature.java create mode 100644 google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/CloudFunctionsFeature.java create mode 100644 google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/CloudSqlFeature.java create mode 100644 google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/OpenCensusFeature.java create mode 100644 google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/SpannerFeature.java create mode 100644 google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/ApiClientVersionSubstitutions.java create mode 100644 google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/GaxPropertiesSubstitutions.java create mode 100644 google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/NettyInternalLoggerFactorySubstitutions.java create mode 100644 google-cloud-core-native-support/src/main/resources/META-INF/native-image/com.google.cloud/google-cloud-core/native-image.properties create mode 100644 google-cloud-core-native-support/src/main/resources/META-INF/native-image/com.google.cloud/google-cloud-core/resource-config.json diff --git a/google-cloud-core-bom/pom.xml b/google-cloud-core-bom/pom.xml index 921d50165a..b3b1f990f5 100644 --- a/google-cloud-core-bom/pom.xml +++ b/google-cloud-core-bom/pom.xml @@ -75,6 +75,11 @@ google-cloud-core-http 2.3.2-SNAPSHOT + + com.google.cloud + google-cloud-core-native-support + 2.3.2-SNAPSHOT + diff --git a/google-cloud-core-native-support/pom.xml b/google-cloud-core-native-support/pom.xml new file mode 100644 index 0000000000..340166761b --- /dev/null +++ b/google-cloud-core-native-support/pom.xml @@ -0,0 +1,36 @@ + + + + 4.0.0 + com.google.cloud + google-cloud-core-native-support + 2.3.2-SNAPSHOT + jar + + + google-cloud-core-parent + com.google.cloud + 2.3.2-SNAPSHOT + + + + Core gRPC module for the google-cloud. + + + + + org.graalvm.nativeimage + svm + provided + + + + io.grpc + grpc-netty-shaded + provided + + + + \ No newline at end of file diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/GoogleJsonClientFeature.java b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/GoogleJsonClientFeature.java new file mode 100644 index 0000000000..8b3975bd8c --- /dev/null +++ b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/GoogleJsonClientFeature.java @@ -0,0 +1,113 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.nativeimage.features; + +import static com.google.cloud.nativeimage.features.NativeImageUtils.registerClassForReflection; + +import com.oracle.svm.core.annotate.AutomaticFeature; +import com.oracle.svm.core.configure.ResourcesRegistry; +import org.graalvm.nativeimage.ImageSingletons; +import org.graalvm.nativeimage.hosted.Feature; + +/** + * Configures Native Image settings for the Google JSON Client. + */ +@AutomaticFeature +final class GoogleJsonClientFeature implements Feature { + + private static final String GOOGLE_API_CLIENT_CLASS = + "com.google.api.client.googleapis.services.json.AbstractGoogleJsonClient"; + + private static final String GOOGLE_API_CLIENT_REQUEST_CLASS = + "com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest"; + + private static final String GENERIC_JSON_CLASS = + "com.google.api.client.json.GenericJson"; + + @Override + public void beforeAnalysis(BeforeAnalysisAccess access) { + loadApiClient(access); + loadHttpClient(access); + loadMiscClasses(access); + } + + private void loadApiClient(BeforeAnalysisAccess access) { + // For com.google.api-client:google-api-client + Class googleApiClientClass = access.findClassByName(GOOGLE_API_CLIENT_CLASS); + + if (googleApiClientClass != null) { + // All reachable instances of the AbstractGoogleJsonClient must be registered. + access.registerSubtypeReachabilityHandler( + (duringAccess, subtype) -> registerClassForReflection(access, subtype.getName()), + googleApiClientClass); + + // All reachable instances of the AbstractGoogleJsonClientRequest must be registered. + access.registerSubtypeReachabilityHandler( + (duringAccess, subtype) -> registerClassForReflection(access, subtype.getName()), + access.findClassByName(GOOGLE_API_CLIENT_REQUEST_CLASS)); + + // Resources + ResourcesRegistry resourcesRegistry = ImageSingletons.lookup(ResourcesRegistry.class); + resourcesRegistry.addResources( + "\\Qcom/google/api/client/googleapis/google-api-client.properties\\E"); + resourcesRegistry.addResources( + "\\Qcom/google/api/client/googleapis/google.p12\\E"); + resourcesRegistry.addResources( + "\\Qcom/google/api/client/http/google-http-client.properties\\E"); + } + } + + private void loadHttpClient(BeforeAnalysisAccess access) { + // For com.google.http-client:google-http-client + Class genericJsonClass = access.findClassByName(GENERIC_JSON_CLASS); + + if (genericJsonClass != null) { + // All reachable instances of GenericJson must be registered. + access.registerSubtypeReachabilityHandler( + (duringAccess, subtype) -> registerClassForReflection(access, subtype.getName()), + genericJsonClass); + + registerClassForReflection( + access, "com.google.api.client.util.GenericData"); + registerClassForReflection( + access, "com.google.api.client.json.webtoken.JsonWebToken"); + registerClassForReflection( + access, "com.google.api.client.json.webtoken.JsonWebToken$Header"); + registerClassForReflection( + access, "com.google.api.client.json.webtoken.JsonWebToken$Payload"); + registerClassForReflection( + access, "com.google.api.client.json.webtoken.JsonWebSignature$Header"); + registerClassForReflection( + access, "com.google.api.client.json.webtoken.JsonWebSignature"); + registerClassForReflection( + access, "com.google.api.client.http.UrlEncodedContent"); + registerClassForReflection( + access, "com.google.api.client.http.GenericUrl"); + registerClassForReflection( + access, "com.google.api.client.http.HttpRequest"); + registerClassForReflection( + access, "com.google.api.client.http.HttpHeaders"); + } + } + + private void loadMiscClasses(BeforeAnalysisAccess access) { + registerClassForReflection( + access, "com.google.common.util.concurrent.AbstractFuture"); + registerClassForReflection( + access, "com.google.common.util.concurrent.AbstractFuture$Waiter"); + } +} diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/GrpcNettyFeature.java b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/GrpcNettyFeature.java new file mode 100644 index 0000000000..3c512c2796 --- /dev/null +++ b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/GrpcNettyFeature.java @@ -0,0 +1,132 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.nativeimage.features; + +import static com.google.cloud.nativeimage.features.NativeImageUtils.registerClassForReflection; +import static com.google.cloud.nativeimage.features.NativeImageUtils.registerClassHierarchyForReflection; +import static com.google.cloud.nativeimage.features.NativeImageUtils.registerForReflectiveInstantiation; +import static com.google.cloud.nativeimage.features.NativeImageUtils.registerForUnsafeFieldAccess; + +import com.oracle.svm.core.annotate.AutomaticFeature; +import org.graalvm.nativeimage.hosted.Feature; + +/** + * Configures Native Image settings for the grpc-netty-shaded dependency. + */ +@AutomaticFeature +final class GrpcNettyFeature implements Feature { + + private static final String GRPC_NETTY_SHADED_CLASS = + "io.grpc.netty.shaded.io.grpc.netty.NettyServer"; + + private static final String GOOGLE_AUTH_CLASS = + "com.google.auth.oauth2.ServiceAccountCredentials"; + + @Override + public void beforeAnalysis(BeforeAnalysisAccess access) { + loadGoogleAuthClasses(access); + loadGrpcNettyClasses(access); + loadMiscClasses(access); + } + + private static void loadGoogleAuthClasses(BeforeAnalysisAccess access) { + // For com.google.auth:google-auth-library-oauth2-http + Class authClass = access.findClassByName(GOOGLE_AUTH_CLASS); + if (authClass != null) { + registerClassHierarchyForReflection( + access, "com.google.auth.oauth2.ServiceAccountCredentials"); + registerClassHierarchyForReflection( + access, "com.google.auth.oauth2.ServiceAccountJwtAccessCredentials"); + } + } + + private static void loadGrpcNettyClasses(BeforeAnalysisAccess access) { + // For io.grpc:grpc-netty-shaded + Class nettyShadedClass = access.findClassByName(GRPC_NETTY_SHADED_CLASS); + if (nettyShadedClass != null) { + // Misc. classes used by grpc-netty-shaded + registerForReflectiveInstantiation( + access, "io.grpc.netty.shaded.io.netty.channel.socket.nio.NioSocketChannel"); + registerClassForReflection( + access, "io.grpc.netty.shaded.io.netty.util.internal.NativeLibraryUtil"); + registerClassForReflection( + access, "io.grpc.netty.shaded.io.netty.util.ReferenceCountUtil"); + registerClassForReflection( + access, "io.grpc.netty.shaded.io.netty.buffer.AbstractByteBufAllocator"); + + // Epoll Libraries + registerClassForReflection( + access, "io.grpc.netty.shaded.io.netty.channel.epoll.Epoll"); + registerClassForReflection( + access, "io.grpc.netty.shaded.io.netty.channel.epoll.EpollChannelOption"); + registerClassForReflection( + access, "io.grpc.netty.shaded.io.netty.channel.epoll.EpollEventLoopGroup"); + registerForReflectiveInstantiation( + access, "io.grpc.netty.shaded.io.netty.channel.epoll.EpollServerSocketChannel"); + registerForReflectiveInstantiation( + access, "io.grpc.netty.shaded.io.netty.channel.epoll.EpollSocketChannel"); + + // Unsafe field accesses + registerForUnsafeFieldAccess( + access, + "io.grpc.netty.shaded.io.netty.util.internal.shaded." + + "org.jctools.queues.MpscArrayQueueProducerIndexField", + "producerIndex"); + registerForUnsafeFieldAccess( + access, + "io.grpc.netty.shaded.io.netty.util.internal.shaded." + + "org.jctools.queues.MpscArrayQueueProducerLimitField", + "producerLimit"); + registerForUnsafeFieldAccess( + access, + "io.grpc.netty.shaded.io.netty.util.internal.shaded." + + "org.jctools.queues.MpscArrayQueueConsumerIndexField", + "consumerIndex"); + registerForUnsafeFieldAccess( + access, + "io.grpc.netty.shaded.io.netty.util.internal.shaded." + + "org.jctools.queues.BaseMpscLinkedArrayQueueProducerFields", + "producerIndex"); + registerForUnsafeFieldAccess( + access, + "io.grpc.netty.shaded.io.netty.util.internal.shaded." + + "org.jctools.queues.BaseMpscLinkedArrayQueueColdProducerFields", + "producerLimit"); + registerForUnsafeFieldAccess( + access, + "io.grpc.netty.shaded.io.netty.util.internal.shaded." + + "org.jctools.queues.BaseMpscLinkedArrayQueueConsumerFields", + "consumerIndex"); + } + } + + /** + * Miscellaneous classes that need to be registered coming from various JARs. + */ + private static void loadMiscClasses(BeforeAnalysisAccess access) { + registerClassHierarchyForReflection( + access, "com.google.protobuf.DescriptorProtos"); + registerClassForReflection(access, "com.google.api.FieldBehavior"); + + registerForUnsafeFieldAccess( + access, "javax.net.ssl.SSLContext", "contextSpi"); + registerClassForReflection( + access, "java.lang.management.ManagementFactory"); + registerClassForReflection( + access, "java.lang.management.RuntimeMXBean"); + } +} diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/NativeImageUtils.java b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/NativeImageUtils.java new file mode 100644 index 0000000000..664c7958d0 --- /dev/null +++ b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/NativeImageUtils.java @@ -0,0 +1,194 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.nativeimage.features; + +import java.io.IOException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.net.JarURLConnection; +import java.net.URL; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.logging.Logger; +import org.graalvm.nativeimage.hosted.Feature.FeatureAccess; +import org.graalvm.nativeimage.hosted.RuntimeReflection; + +/** + * Internal class offering helper methods for registering methods/classes for reflection. + */ +public class NativeImageUtils { + + private static final Logger LOGGER = Logger.getLogger(NativeImageUtils.class.getName()); + + /** + * Returns the method of a class or fails if it is not present. + */ + public static Method getMethodOrFail( + Class clazz, String methodName, Class... params) { + try { + return clazz.getDeclaredMethod(methodName, params); + } catch (NoSuchMethodException e) { + throw new RuntimeException( + "Failed to find method " + methodName + " for class " + clazz.getName(), e); + } + } + + /** + * Registers a class for reflective construction via its default constructor. + */ + public static void registerForReflectiveInstantiation(FeatureAccess access, String className) { + Class clazz = access.findClassByName(className); + if (clazz != null) { + RuntimeReflection.register(clazz); + RuntimeReflection.registerForReflectiveInstantiation(clazz); + } else { + LOGGER.warning( + "Failed to find " + className + " on the classpath for reflective instantiation."); + } + } + + /** + * Registers all constructors of a class for reflection. + */ + public static void registerConstructorsForReflection(FeatureAccess access, String name) { + Class clazz = access.findClassByName(name); + if (clazz != null) { + RuntimeReflection.register(clazz); + RuntimeReflection.register(clazz.getDeclaredConstructors()); + } else { + LOGGER.warning( + "Failed to find " + name + " on the classpath for reflection."); + } + } + + /** + * Registers an entire class for reflection use. + */ + public static void registerClassForReflection(FeatureAccess access, String name) { + Class clazz = access.findClassByName(name); + if (clazz != null) { + RuntimeReflection.register(clazz); + RuntimeReflection.register(clazz.getDeclaredConstructors()); + RuntimeReflection.register(clazz.getDeclaredFields()); + RuntimeReflection.register(clazz.getDeclaredMethods()); + } else { + LOGGER.warning( + "Failed to find " + name + " on the classpath for reflection."); + } + } + + /** + * Registers the transitive class hierarchy of the provided {@code className} for reflection. + * + *

The transitive class hierarchy contains the class itself and its transitive set of + * *non-private* nested subclasses. + */ + public static void registerClassHierarchyForReflection(FeatureAccess access, String className) { + Class clazz = access.findClassByName(className); + if (clazz != null) { + registerClassForReflection(access, className); + for (Class nestedClass : clazz.getDeclaredClasses()) { + if (!Modifier.isPrivate(nestedClass.getModifiers())) { + registerClassHierarchyForReflection(access, nestedClass.getName()); + } + } + } else { + LOGGER.warning( + "Failed to find " + className + " on the classpath for reflection."); + } + } + + /** + * Registers a class for unsafe reflective field access. + */ + public static void registerForUnsafeFieldAccess( + FeatureAccess access, String className, String... fields) { + Class clazz = access.findClassByName(className); + if (clazz != null) { + RuntimeReflection.register(clazz); + for (String fieldName : fields) { + try { + RuntimeReflection.register(clazz.getDeclaredField(fieldName)); + } catch (NoSuchFieldException ex) { + LOGGER.warning("Failed to register field " + fieldName + " for class " + className); + LOGGER.warning(ex.getMessage()); + } + } + } else { + LOGGER.warning( + "Failed to find " + className + + " on the classpath for unsafe fields access registration."); + } + } + + /** + * Registers all the classes under the specified package for reflection. + */ + public static void registerPackageForReflection(FeatureAccess access, String packageName) { + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + + try { + String path = packageName.replace('.', '/'); + + Enumeration resources = classLoader.getResources(path); + while (resources.hasMoreElements()) { + URL url = resources.nextElement(); + + URLConnection connection = url.openConnection(); + if (connection instanceof JarURLConnection) { + List classes = findClassesInJar((JarURLConnection) connection, packageName); + for (String className : classes) { + registerClassHierarchyForReflection(access, className); + } + } + } + } catch (IOException e) { + throw new RuntimeException("Failed to load classes under package name.", e); + } + } + + private static List findClassesInJar( + JarURLConnection urlConnection, String packageName) throws IOException { + + List result = new ArrayList<>(); + + final JarFile jarFile = urlConnection.getJarFile(); + final Enumeration entries = jarFile.entries(); + + while (entries.hasMoreElements()) { + JarEntry entry = entries.nextElement(); + String entryName = entry.getName(); + + if (entryName.endsWith(".class")) { + String javaClassName = + entryName + .replace(".class", "") + .replace('/', '.'); + + if (javaClassName.startsWith(packageName)) { + result.add(javaClassName); + } + } + } + + return result; + } +} diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/ProtobufMessageFeature.java b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/ProtobufMessageFeature.java new file mode 100644 index 0000000000..7ee1a045de --- /dev/null +++ b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/ProtobufMessageFeature.java @@ -0,0 +1,109 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.nativeimage.features; + +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.List; +import org.graalvm.nativeimage.hosted.Feature; +import org.graalvm.nativeimage.hosted.RuntimeReflection; + +/** + * A optional feature which registers reflective usages of the GRPC Protobuf libraries. + * + *

This feature is only needed if you need to access proto objects reflectively + * (such as printing/logging proto objects). + * + *

To add this feature, add + * "--feature com.google.cloud.nativeimage.features.ProtobufMessageFeature" + * to your GraalVM configuration. + */ +final class ProtobufMessageFeature implements Feature { + + // Proto classes to check on the classpath. + private static final String PROTO_MESSAGE_CLASS = "com.google.protobuf.GeneratedMessageV3"; + private static final String PROTO_ENUM_CLASS = "com.google.protobuf.ProtocolMessageEnum"; + private static final String ENUM_VAL_DESCRIPTOR_CLASS = + "com.google.protobuf.Descriptors$EnumValueDescriptor"; + + // Prefixes of methods accessed reflectively by + // com.google.protobuf.GeneratedMessageV3$ReflectionInvoker + private static final List METHOD_ACCESSOR_PREFIXES = + Arrays.asList("get", "set", "has", "add", "clear", "newBuilder"); + + @Override + public void beforeAnalysis(BeforeAnalysisAccess access) { + Class protoMessageClass = access.findClassByName(PROTO_MESSAGE_CLASS); + if (protoMessageClass != null) { + Method internalAccessorMethod = + NativeImageUtils.getMethodOrFail(protoMessageClass, "internalGetFieldAccessorTable"); + + // Finds every class whose `internalGetFieldAccessorTable()` is reached and registers it. + // `internalGetFieldAccessorTable()` is used downstream to access the class reflectively. + access.registerMethodOverrideReachabilityHandler( + (duringAccess, method) -> { + registerFieldAccessors(method.getDeclaringClass()); + registerFieldAccessors(getBuilderClass(method.getDeclaringClass())); + }, + internalAccessorMethod); + } + + Class protoEnumClass = access.findClassByName(PROTO_ENUM_CLASS); + if (protoEnumClass != null) { + // Finds every reachable proto enum class and registers specific methods for reflection. + access.registerSubtypeReachabilityHandler( + (duringAccess, subtypeClass) -> { + if (!PROTO_ENUM_CLASS.equals(subtypeClass.getName())) { + Method method = NativeImageUtils.getMethodOrFail( + subtypeClass, + "valueOf", + duringAccess.findClassByName(ENUM_VAL_DESCRIPTOR_CLASS)); + RuntimeReflection.register(method); + + method = NativeImageUtils.getMethodOrFail(subtypeClass, "getValueDescriptor"); + RuntimeReflection.register(method); + } + }, + protoEnumClass); + } + } + + /** + * Given a proto class, registers the public accessor methods for the provided proto class. + */ + private static void registerFieldAccessors(Class protoClass) { + for (Method method : protoClass.getMethods()) { + boolean hasAccessorPrefix = + METHOD_ACCESSOR_PREFIXES.stream().anyMatch(prefix -> method.getName().startsWith(prefix)); + if (hasAccessorPrefix) { + RuntimeReflection.register(method); + } + } + } + + /** + * Given a proto class, returns the Builder nested class. + */ + private static Class getBuilderClass(Class protoClass) { + for (Class clazz : protoClass.getClasses()) { + if (clazz.getName().endsWith("Builder")) { + return clazz; + } + } + return null; + } +} diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/CloudFunctionsFeature.java b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/CloudFunctionsFeature.java new file mode 100644 index 0000000000..06b6ef9556 --- /dev/null +++ b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/CloudFunctionsFeature.java @@ -0,0 +1,149 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.nativeimage.features.clients; + +import static com.google.cloud.nativeimage.features.NativeImageUtils.registerClassForReflection; +import static com.google.cloud.nativeimage.features.NativeImageUtils.registerClassHierarchyForReflection; + +import com.oracle.svm.core.annotate.AutomaticFeature; +import com.oracle.svm.core.configure.ResourcesRegistry; +import java.io.IOException; +import java.lang.reflect.Modifier; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.Enumeration; +import java.util.List; +import java.util.function.Consumer; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.stream.Collectors; +import org.graalvm.nativeimage.ImageSingletons; +import org.graalvm.nativeimage.hosted.Feature; +import org.graalvm.nativeimage.hosted.RuntimeReflection; + +/** + * A feature which registers reflective usages of the Cloud Functions library. + */ +@AutomaticFeature +final class CloudFunctionsFeature implements Feature { + + private static final String FUNCTION_INVOKER_CLASS = + "com.google.cloud.functions.invoker.runner.Invoker"; + + private static final List FUNCTIONS_CLASSES = + Arrays.asList( + "com.google.cloud.functions.HttpFunction", + "com.google.cloud.functions.RawBackgroundFunction", + "com.google.cloud.functions.BackgroundFunction"); + + @Override + public void beforeAnalysis(BeforeAnalysisAccess access) { + Class invokerClass = access.findClassByName(FUNCTION_INVOKER_CLASS); + if (invokerClass != null) { + // JCommander libraries + registerClassForReflection( + access, "com.beust.jcommander.converters.StringConverter"); + registerClassForReflection( + access, "com.beust.jcommander.validators.NoValidator"); + registerClassForReflection( + access, "com.beust.jcommander.validators.NoValueValidator"); + + // Jetty libraries + registerClassForReflection(access, "org.eclipse.jetty.http.HttpTokens"); + registerClassForReflection(access, "org.eclipse.jetty.util.TypeUtil"); + + // Cloud Functions core + registerClassForReflection( + access, "com.google.cloud.functions.invoker.runner.Invoker$Options"); + + // Register Jetty Resources. + ResourcesRegistry resourcesRegistry = ImageSingletons.lookup(ResourcesRegistry.class); + resourcesRegistry.addResources( + "\\QMETA-INF/services/org.eclipse.jetty.http.HttpFieldPreEncoder\\E"); + resourcesRegistry.addResources("\\Qorg/eclipse/jetty/http/encoding.properties\\E"); + resourcesRegistry.addResources("\\Qorg/eclipse/jetty/http/mime.properties\\E"); + resourcesRegistry.addResources("\\Qorg/eclipse/jetty/version/build.properties\\E"); + resourcesRegistry.addResourceBundles("javax.servlet.LocalStrings"); + resourcesRegistry.addResourceBundles("javax.servlet.http.LocalStrings"); + + // Register user-implemented Function classes + List> functionClasses = + FUNCTIONS_CLASSES.stream() + .map(name -> access.findClassByName(name)) + .collect(Collectors.toList()); + + scanJarClasspath(access, clazz -> { + boolean isFunctionSubtype = functionClasses.stream() + .anyMatch(function -> + function.isAssignableFrom(clazz) && !Modifier.isAbstract(clazz.getModifiers())); + + if (isFunctionSubtype) { + RuntimeReflection.register(clazz); + RuntimeReflection.register(clazz.getDeclaredConstructors()); + RuntimeReflection.register(clazz.getDeclaredMethods()); + + // This part is to register the parameterized class of BackgroundFunctions + // for reflection; i.e. register type T in BackgroundFunction + for (Type type : clazz.getGenericInterfaces()) { + if (type instanceof ParameterizedType) { + ParameterizedType paramType = (ParameterizedType) type; + for (Type argument : paramType.getActualTypeArguments()) { + registerClassHierarchyForReflection(access, argument.getTypeName()); + } + } + } + } + }); + } + } + + /** + * Scan the JAR classpath for classes. + * The {@code classProcessorFunction} is run once for each class in the classpath. + */ + private static void scanJarClasspath( + FeatureAccess access, Consumer> classProcessorCallback) { + + List classPath = access.getApplicationClassPath(); + try { + for (Path path : classPath) { + JarFile jarFile = new JarFile(path.toFile()); + Enumeration entries = jarFile.entries(); + + while (entries.hasMoreElements()) { + JarEntry jarEntry = entries.nextElement(); + String fileName = jarEntry.getName(); + if (fileName.endsWith(".class")) { + String className = + fileName + .substring(0, fileName.length() - 6) + .replaceAll("/", "."); + + Class clazz = access.findClassByName(className); + if (clazz != null) { + classProcessorCallback.accept(clazz); + } + } + } + } + } catch (IOException e) { + throw new RuntimeException("Failed to read classpath: ", e); + } + } +} diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/CloudSqlFeature.java b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/CloudSqlFeature.java new file mode 100644 index 0000000000..12340d6b56 --- /dev/null +++ b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/CloudSqlFeature.java @@ -0,0 +1,104 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.nativeimage.features.clients; + +import com.google.cloud.nativeimage.features.NativeImageUtils; +import com.oracle.svm.core.annotate.AutomaticFeature; +import com.oracle.svm.core.configure.ResourcesRegistry; +import org.graalvm.nativeimage.ImageSingletons; +import org.graalvm.nativeimage.hosted.Feature; +import org.graalvm.nativeimage.hosted.RuntimeClassInitialization; +import org.graalvm.nativeimage.hosted.RuntimeReflection; + +/** + * Registers GraalVM configuration for the Cloud SQL libraries for MySQL and Postgres. + */ +@AutomaticFeature +final class CloudSqlFeature implements Feature { + + private static final String CLOUD_SQL_SOCKET_CLASS = + "com.google.cloud.sql.core.CoreSocketFactory"; + + private static final String POSTGRES_SOCKET_CLASS = + "com.google.cloud.sql.postgres.SocketFactory"; + + private static final String MYSQL_SOCKET_CLASS = + "com.google.cloud.sql.mysql.SocketFactory"; + + @Override + public void beforeAnalysis(BeforeAnalysisAccess access) { + if (access.findClassByName(CLOUD_SQL_SOCKET_CLASS) == null) { + return; + } + + // The Core Cloud SQL Socket + NativeImageUtils.registerClassForReflection(access, CLOUD_SQL_SOCKET_CLASS); + + // Resources for Cloud SQL + ResourcesRegistry resourcesRegistry = ImageSingletons.lookup(ResourcesRegistry.class); + resourcesRegistry.addResources("\\Qcom.google.cloud.sql/project.properties\\E"); + resourcesRegistry.addResources("\\QMETA-INF/services/java.sql.Driver\\E"); + + // Register Hikari configs if used with Cloud SQL. + if (access.findClassByName("com.zaxxer.hikari.HikariConfig") != null) { + NativeImageUtils.registerClassForReflection( + access, + "com.zaxxer.hikari.HikariConfig"); + + RuntimeReflection.register( + access.findClassByName("[Lcom.zaxxer.hikari.util.ConcurrentBag$IConcurrentBagEntry;")); + + RuntimeReflection.register( + access.findClassByName("[Ljava.sql.Statement;") + ); + } + + // Register PostgreSQL driver config. + if (access.findClassByName(POSTGRES_SOCKET_CLASS) != null) { + NativeImageUtils.registerClassForReflection( + access, "com.google.cloud.sql.postgres.SocketFactory"); + NativeImageUtils.registerClassForReflection( + access, "org.postgresql.PGProperty"); + } + + // Register MySQL driver config. + if (access.findClassByName(MYSQL_SOCKET_CLASS) != null) { + NativeImageUtils.registerClassForReflection( + access, + MYSQL_SOCKET_CLASS); + + NativeImageUtils.registerConstructorsForReflection( + access, + "com.mysql.cj.conf.url.SingleConnectionUrl"); + + NativeImageUtils.registerConstructorsForReflection( + access, + "com.mysql.cj.log.StandardLogger"); + + access.registerSubtypeReachabilityHandler( + (duringAccess, exceptionClass) -> + NativeImageUtils.registerClassForReflection(duringAccess, exceptionClass.getName()), + access.findClassByName("com.mysql.cj.exceptions.CJException")); + + // JDBC classes create socket connections which must be initialized at run time. + RuntimeClassInitialization.initializeAtRunTime("com.mysql.cj.jdbc"); + + // Additional MySQL resources. + resourcesRegistry.addResourceBundles("com.mysql.cj.LocalizedErrorMessages"); + } + } +} diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/OpenCensusFeature.java b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/OpenCensusFeature.java new file mode 100644 index 0000000000..9b57671943 --- /dev/null +++ b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/OpenCensusFeature.java @@ -0,0 +1,43 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.nativeimage.features.clients; + +import static com.google.cloud.nativeimage.features.NativeImageUtils.registerForReflectiveInstantiation; + +import com.oracle.svm.core.annotate.AutomaticFeature; +import org.graalvm.nativeimage.hosted.Feature; + +/** + * Registers reflection usage in OpenCensus libraries. + */ +@AutomaticFeature +final class OpenCensusFeature implements Feature { + + private static final String OPEN_CENSUS_CLASS = "io.opencensus.impl.tags.TagsComponentImpl"; + + @Override + public void beforeAnalysis(BeforeAnalysisAccess access) { + if (access.findClassByName(OPEN_CENSUS_CLASS) != null) { + registerForReflectiveInstantiation( + access, "io.opencensus.impl.metrics.MetricsComponentImpl"); + registerForReflectiveInstantiation( + access, "io.opencensus.impl.tags.TagsComponentImpl"); + registerForReflectiveInstantiation( + access, "io.opencensus.impl.trace.TraceComponentImpl"); + } + } +} diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/SpannerFeature.java b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/SpannerFeature.java new file mode 100644 index 0000000000..b215bd7b23 --- /dev/null +++ b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/SpannerFeature.java @@ -0,0 +1,52 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.nativeimage.features.clients; + +import com.google.cloud.nativeimage.features.NativeImageUtils; +import com.oracle.svm.core.annotate.AutomaticFeature; +import com.oracle.svm.core.configure.ResourcesRegistry; +import org.graalvm.nativeimage.ImageSingletons; +import org.graalvm.nativeimage.hosted.Feature; + +/** + * Registers Spanner library classes for reflection. + */ +@AutomaticFeature +final class SpannerFeature implements Feature { + + private static final String SPANNER_CLASS = "com.google.spanner.v1.SpannerGrpc"; + + @Override + public void beforeAnalysis(BeforeAnalysisAccess access) { + Class spannerClass = access.findClassByName(SPANNER_CLASS); + if (spannerClass != null) { + NativeImageUtils.registerClassHierarchyForReflection( + access, "com.google.spanner.admin.database.v1.Database"); + NativeImageUtils.registerClassHierarchyForReflection( + access, "com.google.spanner.admin.instance.v1.Instance"); + NativeImageUtils.registerClassForReflection( + access, "com.google.spanner.admin.database.v1.RestoreInfo"); + + // Resources + ResourcesRegistry resourcesRegistry = ImageSingletons.lookup(ResourcesRegistry.class); + resourcesRegistry.addResources( + "\\Qcom/google/cloud/spanner/connection/ClientSideStatements.json\\E"); + resourcesRegistry.addResources( + "\\Qcom/google/cloud/spanner/spi/v1/grpc-gcp-apiconfig.json\\E"); + } + } +} diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/ApiClientVersionSubstitutions.java b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/ApiClientVersionSubstitutions.java new file mode 100644 index 0000000000..d3fecb6183 --- /dev/null +++ b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/ApiClientVersionSubstitutions.java @@ -0,0 +1,68 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.nativeimage.features.substitutions; + +import com.oracle.svm.core.annotate.Alias; +import com.oracle.svm.core.annotate.Substitute; +import com.oracle.svm.core.annotate.TargetClass; +import java.util.function.BooleanSupplier; + +/** + * Substitution for setting Java version correctly in the Google Java Http Client. + */ +@TargetClass( + className = + "com.google.api.client.googleapis.services.AbstractGoogleClientRequest$ApiClientVersion", + onlyWith = ApiClientVersionSubstitutions.OnlyIfInClassPath.class) +final class ApiClientVersionSubstitutions { + + @Alias + private String versionString; + + @Substitute + public String toString() { + String[] tokens = versionString.split(" "); + + if (tokens.length > 0 && tokens[0].startsWith("gl-java")) { + tokens[0] += "-graalvm"; + return String.join(" ", tokens); + } else { + return versionString; + } + } + + private ApiClientVersionSubstitutions() { + } + + static class OnlyIfInClassPath implements BooleanSupplier { + + @Override + public boolean getAsBoolean() { + try { + // Note: Set initialize = false to avoid initializing the class when looking it up. + Class.forName( + "com.google.api.client.googleapis.services." + + "AbstractGoogleClientRequest$ApiClientVersion", + false, + Thread.currentThread().getContextClassLoader()); + return true; + } catch (ClassNotFoundException e) { + return false; + } + } + } +} diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/GaxPropertiesSubstitutions.java b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/GaxPropertiesSubstitutions.java new file mode 100644 index 0000000000..9f30424b2b --- /dev/null +++ b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/GaxPropertiesSubstitutions.java @@ -0,0 +1,58 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.nativeimage.features.substitutions; + +import com.oracle.svm.core.annotate.Alias; +import com.oracle.svm.core.annotate.RecomputeFieldValue; +import com.oracle.svm.core.annotate.RecomputeFieldValue.Kind; +import com.oracle.svm.core.annotate.TargetClass; +import java.util.function.BooleanSupplier; + +/** + * This file contains the GaxProperties substitution to correctly set the Java language string + * in API call headers for Native Image users. + */ +@TargetClass( + className = "com.google.api.gax.core.GaxProperties", + onlyWith = GaxPropertiesSubstitutions.OnlyIfInClassPath.class) +final class GaxPropertiesSubstitutions { + + @Alias + @RecomputeFieldValue(kind = Kind.FromAlias) + private static String JAVA_VERSION = System.getProperty("java.version") + "-graalvm"; + + private GaxPropertiesSubstitutions() { + } + + static class OnlyIfInClassPath implements BooleanSupplier { + + @Override + public boolean getAsBoolean() { + try { + // Note: Set initialize = false to avoid initializing the class when looking it up. + Class.forName( + "com.google.api.gax.core.GaxProperties", + false, + Thread.currentThread().getContextClassLoader()); + return true; + } catch (ClassNotFoundException e) { + return false; + } + } + } +} + diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/NettyInternalLoggerFactorySubstitutions.java b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/NettyInternalLoggerFactorySubstitutions.java new file mode 100644 index 0000000000..63d9425999 --- /dev/null +++ b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/NettyInternalLoggerFactorySubstitutions.java @@ -0,0 +1,56 @@ +/* + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.nativeimage.features.substitutions; + +import com.oracle.svm.core.annotate.Substitute; +import com.oracle.svm.core.annotate.TargetClass; +import io.grpc.netty.shaded.io.netty.util.internal.logging.InternalLoggerFactory; +import io.grpc.netty.shaded.io.netty.util.internal.logging.JdkLoggerFactory; +import java.util.function.BooleanSupplier; + +/** + * Substitutions for {@link InternalLoggerFactory} which are needed to avoid dynamic loading + * of logging library. + */ +@TargetClass( + className = "io.grpc.netty.shaded.io.netty.util.internal.logging.InternalLoggerFactory", + onlyWith = NettyInternalLoggerFactorySubstitutions.OnlyIfInClassPath.class +) +final class NettyInternalLoggerFactorySubstitutions { + + @Substitute + private static InternalLoggerFactory newDefaultFactory(String name) { + return JdkLoggerFactory.INSTANCE; + } + + static class OnlyIfInClassPath implements BooleanSupplier { + + @Override + public boolean getAsBoolean() { + try { + // Note: Set initialize = false to avoid initializing the class when looking it up. + Class.forName( + "io.grpc.netty.shaded.io.netty.util.internal.logging.InternalLoggerFactory", + false, + Thread.currentThread().getContextClassLoader()); + return true; + } catch (ClassNotFoundException e) { + return false; + } + } + } +} diff --git a/google-cloud-core-native-support/src/main/resources/META-INF/native-image/com.google.cloud/google-cloud-core/native-image.properties b/google-cloud-core-native-support/src/main/resources/META-INF/native-image/com.google.cloud/google-cloud-core/native-image.properties new file mode 100644 index 0000000000..aa61561066 --- /dev/null +++ b/google-cloud-core-native-support/src/main/resources/META-INF/native-image/com.google.cloud/google-cloud-core/native-image.properties @@ -0,0 +1,14 @@ +Args = --allow-incomplete-classpath \ +--enable-url-protocols=https,http \ +--initialize-at-build-time=org.conscrypt \ +--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,\ + io.grpc.netty.shaded.io.grpc.netty,\ + io.grpc.netty.shaded.io.netty.channel.epoll,\ + io.grpc.netty.shaded.io.netty.channel.unix,\ + io.grpc.netty.shaded.io.netty.handler.ssl,\ + io.grpc.internal.RetriableStream,\ + com.google.api.client.googleapis.services.AbstractGoogleClientRequest$ApiClientVersion,\ + com.google.cloud.firestore.FirestoreImpl diff --git a/google-cloud-core-native-support/src/main/resources/META-INF/native-image/com.google.cloud/google-cloud-core/resource-config.json b/google-cloud-core-native-support/src/main/resources/META-INF/native-image/com.google.cloud/google-cloud-core/resource-config.json new file mode 100644 index 0000000000..3afe5ffebc --- /dev/null +++ b/google-cloud-core-native-support/src/main/resources/META-INF/native-image/com.google.cloud/google-cloud-core/resource-config.json @@ -0,0 +1,13 @@ +{ + "resources":[ + {"pattern":"\\QMETA-INF/native/libio_grpc_netty_shaded_netty_tcnative_linux_x86_64.so\\E"}, + {"pattern":"\\QMETA-INF/native/libio_grpc_netty_shaded_netty_transport_native_epoll_x86_64.so\\E"}, + {"pattern":"\\QMETA-INF/services/io.grpc.LoadBalancerProvider\\E"}, + {"pattern":"\\QMETA-INF/services/io.grpc.ManagedChannelProvider\\E"}, + {"pattern":"\\QMETA-INF/services/io.grpc.NameResolverProvider\\E"}, + {"pattern":"\\QMETA-INF/services/jdk.vm.ci.services.JVMCIServiceLocator\\E"}, + {"pattern":"\\Qdependencies.properties\\E"}, + {"pattern":"\\Qgoogle-http-client.properties\\E"} + ], + "bundles":[] +} diff --git a/pom.xml b/pom.xml index 6fd9ce8312..2e09953a8c 100644 --- a/pom.xml +++ b/pom.xml @@ -159,6 +159,7 @@ 1.32.2 1.40.1 1.42.1 + 21.3.0 3.19.1 0.28.0 1.3.2 @@ -180,6 +181,11 @@ google-cloud-core ${project.version} + + com.google.cloud + google-cloud-core-native-support + ${project.version} + com.google.auth @@ -283,6 +289,14 @@ ${gson.version} + + + org.graalvm.nativeimage + svm + ${graalvm.version} + provided + + com.google.truth @@ -322,6 +336,7 @@ google-cloud-core-http google-cloud-core-grpc google-cloud-core-bom + google-cloud-core-native-support From 5b65cad6f333c50fc38756373d73592d99708cc1 Mon Sep 17 00:00:00 2001 From: Owl Bot Date: Tue, 30 Nov 2021 00:00:55 +0000 Subject: [PATCH 2/8] =?UTF-8?q?=F0=9F=A6=89=20Updates=20from=20OwlBot?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md --- .../features/GoogleJsonClientFeature.java | 42 ++++-------- .../features/GrpcNettyFeature.java | 26 +++---- .../features/NativeImageUtils.java | 52 +++++--------- .../features/ProtobufMessageFeature.java | 26 +++---- .../clients/CloudFunctionsFeature.java | 67 +++++++++---------- .../features/clients/CloudSqlFeature.java | 32 +++------ .../features/clients/OpenCensusFeature.java | 13 ++-- .../features/clients/SpannerFeature.java | 4 +- .../ApiClientVersionSubstitutions.java | 10 +-- .../GaxPropertiesSubstitutions.java | 8 +-- ...ttyInternalLoggerFactorySubstitutions.java | 7 +- 11 files changed, 104 insertions(+), 183 deletions(-) diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/GoogleJsonClientFeature.java b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/GoogleJsonClientFeature.java index 8b3975bd8c..25a3e48336 100644 --- a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/GoogleJsonClientFeature.java +++ b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/GoogleJsonClientFeature.java @@ -23,9 +23,7 @@ import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.hosted.Feature; -/** - * Configures Native Image settings for the Google JSON Client. - */ +/** Configures Native Image settings for the Google JSON Client. */ @AutomaticFeature final class GoogleJsonClientFeature implements Feature { @@ -35,8 +33,7 @@ final class GoogleJsonClientFeature implements Feature { private static final String GOOGLE_API_CLIENT_REQUEST_CLASS = "com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest"; - private static final String GENERIC_JSON_CLASS = - "com.google.api.client.json.GenericJson"; + private static final String GENERIC_JSON_CLASS = "com.google.api.client.json.GenericJson"; @Override public void beforeAnalysis(BeforeAnalysisAccess access) { @@ -64,8 +61,7 @@ private void loadApiClient(BeforeAnalysisAccess access) { ResourcesRegistry resourcesRegistry = ImageSingletons.lookup(ResourcesRegistry.class); resourcesRegistry.addResources( "\\Qcom/google/api/client/googleapis/google-api-client.properties\\E"); - resourcesRegistry.addResources( - "\\Qcom/google/api/client/googleapis/google.p12\\E"); + resourcesRegistry.addResources("\\Qcom/google/api/client/googleapis/google.p12\\E"); resourcesRegistry.addResources( "\\Qcom/google/api/client/http/google-http-client.properties\\E"); } @@ -81,33 +77,23 @@ private void loadHttpClient(BeforeAnalysisAccess access) { (duringAccess, subtype) -> registerClassForReflection(access, subtype.getName()), genericJsonClass); - registerClassForReflection( - access, "com.google.api.client.util.GenericData"); - registerClassForReflection( - access, "com.google.api.client.json.webtoken.JsonWebToken"); - registerClassForReflection( - access, "com.google.api.client.json.webtoken.JsonWebToken$Header"); + registerClassForReflection(access, "com.google.api.client.util.GenericData"); + registerClassForReflection(access, "com.google.api.client.json.webtoken.JsonWebToken"); + registerClassForReflection(access, "com.google.api.client.json.webtoken.JsonWebToken$Header"); registerClassForReflection( access, "com.google.api.client.json.webtoken.JsonWebToken$Payload"); registerClassForReflection( - access, "com.google.api.client.json.webtoken.JsonWebSignature$Header"); - registerClassForReflection( - access, "com.google.api.client.json.webtoken.JsonWebSignature"); - registerClassForReflection( - access, "com.google.api.client.http.UrlEncodedContent"); - registerClassForReflection( - access, "com.google.api.client.http.GenericUrl"); - registerClassForReflection( - access, "com.google.api.client.http.HttpRequest"); - registerClassForReflection( - access, "com.google.api.client.http.HttpHeaders"); + access, "com.google.api.client.json.webtoken.JsonWebSignature$Header"); + registerClassForReflection(access, "com.google.api.client.json.webtoken.JsonWebSignature"); + registerClassForReflection(access, "com.google.api.client.http.UrlEncodedContent"); + registerClassForReflection(access, "com.google.api.client.http.GenericUrl"); + registerClassForReflection(access, "com.google.api.client.http.HttpRequest"); + registerClassForReflection(access, "com.google.api.client.http.HttpHeaders"); } } private void loadMiscClasses(BeforeAnalysisAccess access) { - registerClassForReflection( - access, "com.google.common.util.concurrent.AbstractFuture"); - registerClassForReflection( - access, "com.google.common.util.concurrent.AbstractFuture$Waiter"); + registerClassForReflection(access, "com.google.common.util.concurrent.AbstractFuture"); + registerClassForReflection(access, "com.google.common.util.concurrent.AbstractFuture$Waiter"); } } diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/GrpcNettyFeature.java b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/GrpcNettyFeature.java index 3c512c2796..76dd724d8e 100644 --- a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/GrpcNettyFeature.java +++ b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/GrpcNettyFeature.java @@ -24,9 +24,7 @@ import com.oracle.svm.core.annotate.AutomaticFeature; import org.graalvm.nativeimage.hosted.Feature; -/** - * Configures Native Image settings for the grpc-netty-shaded dependency. - */ +/** Configures Native Image settings for the grpc-netty-shaded dependency. */ @AutomaticFeature final class GrpcNettyFeature implements Feature { @@ -63,14 +61,12 @@ private static void loadGrpcNettyClasses(BeforeAnalysisAccess access) { access, "io.grpc.netty.shaded.io.netty.channel.socket.nio.NioSocketChannel"); registerClassForReflection( access, "io.grpc.netty.shaded.io.netty.util.internal.NativeLibraryUtil"); - registerClassForReflection( - access, "io.grpc.netty.shaded.io.netty.util.ReferenceCountUtil"); + registerClassForReflection(access, "io.grpc.netty.shaded.io.netty.util.ReferenceCountUtil"); registerClassForReflection( access, "io.grpc.netty.shaded.io.netty.buffer.AbstractByteBufAllocator"); // Epoll Libraries - registerClassForReflection( - access, "io.grpc.netty.shaded.io.netty.channel.epoll.Epoll"); + registerClassForReflection(access, "io.grpc.netty.shaded.io.netty.channel.epoll.Epoll"); registerClassForReflection( access, "io.grpc.netty.shaded.io.netty.channel.epoll.EpollChannelOption"); registerClassForReflection( @@ -114,19 +110,13 @@ private static void loadGrpcNettyClasses(BeforeAnalysisAccess access) { } } - /** - * Miscellaneous classes that need to be registered coming from various JARs. - */ + /** Miscellaneous classes that need to be registered coming from various JARs. */ private static void loadMiscClasses(BeforeAnalysisAccess access) { - registerClassHierarchyForReflection( - access, "com.google.protobuf.DescriptorProtos"); + registerClassHierarchyForReflection(access, "com.google.protobuf.DescriptorProtos"); registerClassForReflection(access, "com.google.api.FieldBehavior"); - registerForUnsafeFieldAccess( - access, "javax.net.ssl.SSLContext", "contextSpi"); - registerClassForReflection( - access, "java.lang.management.ManagementFactory"); - registerClassForReflection( - access, "java.lang.management.RuntimeMXBean"); + registerForUnsafeFieldAccess(access, "javax.net.ssl.SSLContext", "contextSpi"); + registerClassForReflection(access, "java.lang.management.ManagementFactory"); + registerClassForReflection(access, "java.lang.management.RuntimeMXBean"); } } diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/NativeImageUtils.java b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/NativeImageUtils.java index 664c7958d0..21a501139b 100644 --- a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/NativeImageUtils.java +++ b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/NativeImageUtils.java @@ -31,18 +31,13 @@ import org.graalvm.nativeimage.hosted.Feature.FeatureAccess; import org.graalvm.nativeimage.hosted.RuntimeReflection; -/** - * Internal class offering helper methods for registering methods/classes for reflection. - */ +/** Internal class offering helper methods for registering methods/classes for reflection. */ public class NativeImageUtils { private static final Logger LOGGER = Logger.getLogger(NativeImageUtils.class.getName()); - /** - * Returns the method of a class or fails if it is not present. - */ - public static Method getMethodOrFail( - Class clazz, String methodName, Class... params) { + /** Returns the method of a class or fails if it is not present. */ + public static Method getMethodOrFail(Class clazz, String methodName, Class... params) { try { return clazz.getDeclaredMethod(methodName, params); } catch (NoSuchMethodException e) { @@ -51,9 +46,7 @@ public static Method getMethodOrFail( } } - /** - * Registers a class for reflective construction via its default constructor. - */ + /** Registers a class for reflective construction via its default constructor. */ public static void registerForReflectiveInstantiation(FeatureAccess access, String className) { Class clazz = access.findClassByName(className); if (clazz != null) { @@ -65,23 +58,18 @@ public static void registerForReflectiveInstantiation(FeatureAccess access, Stri } } - /** - * Registers all constructors of a class for reflection. - */ + /** Registers all constructors of a class for reflection. */ public static void registerConstructorsForReflection(FeatureAccess access, String name) { Class clazz = access.findClassByName(name); if (clazz != null) { RuntimeReflection.register(clazz); RuntimeReflection.register(clazz.getDeclaredConstructors()); } else { - LOGGER.warning( - "Failed to find " + name + " on the classpath for reflection."); + LOGGER.warning("Failed to find " + name + " on the classpath for reflection."); } } - /** - * Registers an entire class for reflection use. - */ + /** Registers an entire class for reflection use. */ public static void registerClassForReflection(FeatureAccess access, String name) { Class clazz = access.findClassByName(name); if (clazz != null) { @@ -90,8 +78,7 @@ public static void registerClassForReflection(FeatureAccess access, String name) RuntimeReflection.register(clazz.getDeclaredFields()); RuntimeReflection.register(clazz.getDeclaredMethods()); } else { - LOGGER.warning( - "Failed to find " + name + " on the classpath for reflection."); + LOGGER.warning("Failed to find " + name + " on the classpath for reflection."); } } @@ -111,14 +98,11 @@ public static void registerClassHierarchyForReflection(FeatureAccess access, Str } } } else { - LOGGER.warning( - "Failed to find " + className + " on the classpath for reflection."); + LOGGER.warning("Failed to find " + className + " on the classpath for reflection."); } } - /** - * Registers a class for unsafe reflective field access. - */ + /** Registers a class for unsafe reflective field access. */ public static void registerForUnsafeFieldAccess( FeatureAccess access, String className, String... fields) { Class clazz = access.findClassByName(className); @@ -134,14 +118,13 @@ public static void registerForUnsafeFieldAccess( } } else { LOGGER.warning( - "Failed to find " + className + "Failed to find " + + className + " on the classpath for unsafe fields access registration."); } } - /** - * Registers all the classes under the specified package for reflection. - */ + /** Registers all the classes under the specified package for reflection. */ public static void registerPackageForReflection(FeatureAccess access, String packageName) { ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); @@ -165,8 +148,8 @@ public static void registerPackageForReflection(FeatureAccess access, String pac } } - private static List findClassesInJar( - JarURLConnection urlConnection, String packageName) throws IOException { + private static List findClassesInJar(JarURLConnection urlConnection, String packageName) + throws IOException { List result = new ArrayList<>(); @@ -178,10 +161,7 @@ private static List findClassesInJar( String entryName = entry.getName(); if (entryName.endsWith(".class")) { - String javaClassName = - entryName - .replace(".class", "") - .replace('/', '.'); + String javaClassName = entryName.replace(".class", "").replace('/', '.'); if (javaClassName.startsWith(packageName)) { result.add(javaClassName); diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/ProtobufMessageFeature.java b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/ProtobufMessageFeature.java index 7ee1a045de..92d82e064a 100644 --- a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/ProtobufMessageFeature.java +++ b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/ProtobufMessageFeature.java @@ -25,12 +25,11 @@ /** * A optional feature which registers reflective usages of the GRPC Protobuf libraries. * - *

This feature is only needed if you need to access proto objects reflectively - * (such as printing/logging proto objects). + *

This feature is only needed if you need to access proto objects reflectively (such as + * printing/logging proto objects). * - *

To add this feature, add - * "--feature com.google.cloud.nativeimage.features.ProtobufMessageFeature" - * to your GraalVM configuration. + *

To add this feature, add "--feature + * com.google.cloud.nativeimage.features.ProtobufMessageFeature" to your GraalVM configuration. */ final class ProtobufMessageFeature implements Feature { @@ -68,10 +67,11 @@ public void beforeAnalysis(BeforeAnalysisAccess access) { access.registerSubtypeReachabilityHandler( (duringAccess, subtypeClass) -> { if (!PROTO_ENUM_CLASS.equals(subtypeClass.getName())) { - Method method = NativeImageUtils.getMethodOrFail( - subtypeClass, - "valueOf", - duringAccess.findClassByName(ENUM_VAL_DESCRIPTOR_CLASS)); + Method method = + NativeImageUtils.getMethodOrFail( + subtypeClass, + "valueOf", + duringAccess.findClassByName(ENUM_VAL_DESCRIPTOR_CLASS)); RuntimeReflection.register(method); method = NativeImageUtils.getMethodOrFail(subtypeClass, "getValueDescriptor"); @@ -82,9 +82,7 @@ public void beforeAnalysis(BeforeAnalysisAccess access) { } } - /** - * Given a proto class, registers the public accessor methods for the provided proto class. - */ + /** Given a proto class, registers the public accessor methods for the provided proto class. */ private static void registerFieldAccessors(Class protoClass) { for (Method method : protoClass.getMethods()) { boolean hasAccessorPrefix = @@ -95,9 +93,7 @@ private static void registerFieldAccessors(Class protoClass) { } } - /** - * Given a proto class, returns the Builder nested class. - */ + /** Given a proto class, returns the Builder nested class. */ private static Class getBuilderClass(Class protoClass) { for (Class clazz : protoClass.getClasses()) { if (clazz.getName().endsWith("Builder")) { diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/CloudFunctionsFeature.java b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/CloudFunctionsFeature.java index 06b6ef9556..1312f5ad37 100644 --- a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/CloudFunctionsFeature.java +++ b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/CloudFunctionsFeature.java @@ -37,9 +37,7 @@ import org.graalvm.nativeimage.hosted.Feature; import org.graalvm.nativeimage.hosted.RuntimeReflection; -/** - * A feature which registers reflective usages of the Cloud Functions library. - */ +/** A feature which registers reflective usages of the Cloud Functions library. */ @AutomaticFeature final class CloudFunctionsFeature implements Feature { @@ -57,12 +55,9 @@ public void beforeAnalysis(BeforeAnalysisAccess access) { Class invokerClass = access.findClassByName(FUNCTION_INVOKER_CLASS); if (invokerClass != null) { // JCommander libraries - registerClassForReflection( - access, "com.beust.jcommander.converters.StringConverter"); - registerClassForReflection( - access, "com.beust.jcommander.validators.NoValidator"); - registerClassForReflection( - access, "com.beust.jcommander.validators.NoValueValidator"); + registerClassForReflection(access, "com.beust.jcommander.converters.StringConverter"); + registerClassForReflection(access, "com.beust.jcommander.validators.NoValidator"); + registerClassForReflection(access, "com.beust.jcommander.validators.NoValueValidator"); // Jetty libraries registerClassForReflection(access, "org.eclipse.jetty.http.HttpTokens"); @@ -88,34 +83,39 @@ public void beforeAnalysis(BeforeAnalysisAccess access) { .map(name -> access.findClassByName(name)) .collect(Collectors.toList()); - scanJarClasspath(access, clazz -> { - boolean isFunctionSubtype = functionClasses.stream() - .anyMatch(function -> - function.isAssignableFrom(clazz) && !Modifier.isAbstract(clazz.getModifiers())); - - if (isFunctionSubtype) { - RuntimeReflection.register(clazz); - RuntimeReflection.register(clazz.getDeclaredConstructors()); - RuntimeReflection.register(clazz.getDeclaredMethods()); - - // This part is to register the parameterized class of BackgroundFunctions - // for reflection; i.e. register type T in BackgroundFunction - for (Type type : clazz.getGenericInterfaces()) { - if (type instanceof ParameterizedType) { - ParameterizedType paramType = (ParameterizedType) type; - for (Type argument : paramType.getActualTypeArguments()) { - registerClassHierarchyForReflection(access, argument.getTypeName()); + scanJarClasspath( + access, + clazz -> { + boolean isFunctionSubtype = + functionClasses.stream() + .anyMatch( + function -> + function.isAssignableFrom(clazz) + && !Modifier.isAbstract(clazz.getModifiers())); + + if (isFunctionSubtype) { + RuntimeReflection.register(clazz); + RuntimeReflection.register(clazz.getDeclaredConstructors()); + RuntimeReflection.register(clazz.getDeclaredMethods()); + + // This part is to register the parameterized class of BackgroundFunctions + // for reflection; i.e. register type T in BackgroundFunction + for (Type type : clazz.getGenericInterfaces()) { + if (type instanceof ParameterizedType) { + ParameterizedType paramType = (ParameterizedType) type; + for (Type argument : paramType.getActualTypeArguments()) { + registerClassHierarchyForReflection(access, argument.getTypeName()); + } + } } } - } - } - }); + }); } } /** - * Scan the JAR classpath for classes. - * The {@code classProcessorFunction} is run once for each class in the classpath. + * Scan the JAR classpath for classes. The {@code classProcessorFunction} is run once for each + * class in the classpath. */ private static void scanJarClasspath( FeatureAccess access, Consumer> classProcessorCallback) { @@ -130,10 +130,7 @@ private static void scanJarClasspath( JarEntry jarEntry = entries.nextElement(); String fileName = jarEntry.getName(); if (fileName.endsWith(".class")) { - String className = - fileName - .substring(0, fileName.length() - 6) - .replaceAll("/", "."); + String className = fileName.substring(0, fileName.length() - 6).replaceAll("/", "."); Class clazz = access.findClassByName(className); if (clazz != null) { diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/CloudSqlFeature.java b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/CloudSqlFeature.java index 12340d6b56..d8e3f89889 100644 --- a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/CloudSqlFeature.java +++ b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/CloudSqlFeature.java @@ -24,20 +24,16 @@ import org.graalvm.nativeimage.hosted.RuntimeClassInitialization; import org.graalvm.nativeimage.hosted.RuntimeReflection; -/** - * Registers GraalVM configuration for the Cloud SQL libraries for MySQL and Postgres. - */ +/** Registers GraalVM configuration for the Cloud SQL libraries for MySQL and Postgres. */ @AutomaticFeature final class CloudSqlFeature implements Feature { private static final String CLOUD_SQL_SOCKET_CLASS = "com.google.cloud.sql.core.CoreSocketFactory"; - private static final String POSTGRES_SOCKET_CLASS = - "com.google.cloud.sql.postgres.SocketFactory"; + private static final String POSTGRES_SOCKET_CLASS = "com.google.cloud.sql.postgres.SocketFactory"; - private static final String MYSQL_SOCKET_CLASS = - "com.google.cloud.sql.mysql.SocketFactory"; + private static final String MYSQL_SOCKET_CLASS = "com.google.cloud.sql.mysql.SocketFactory"; @Override public void beforeAnalysis(BeforeAnalysisAccess access) { @@ -55,39 +51,29 @@ public void beforeAnalysis(BeforeAnalysisAccess access) { // Register Hikari configs if used with Cloud SQL. if (access.findClassByName("com.zaxxer.hikari.HikariConfig") != null) { - NativeImageUtils.registerClassForReflection( - access, - "com.zaxxer.hikari.HikariConfig"); + NativeImageUtils.registerClassForReflection(access, "com.zaxxer.hikari.HikariConfig"); RuntimeReflection.register( access.findClassByName("[Lcom.zaxxer.hikari.util.ConcurrentBag$IConcurrentBagEntry;")); - RuntimeReflection.register( - access.findClassByName("[Ljava.sql.Statement;") - ); + RuntimeReflection.register(access.findClassByName("[Ljava.sql.Statement;")); } // Register PostgreSQL driver config. if (access.findClassByName(POSTGRES_SOCKET_CLASS) != null) { NativeImageUtils.registerClassForReflection( access, "com.google.cloud.sql.postgres.SocketFactory"); - NativeImageUtils.registerClassForReflection( - access, "org.postgresql.PGProperty"); + NativeImageUtils.registerClassForReflection(access, "org.postgresql.PGProperty"); } // Register MySQL driver config. if (access.findClassByName(MYSQL_SOCKET_CLASS) != null) { - NativeImageUtils.registerClassForReflection( - access, - MYSQL_SOCKET_CLASS); + NativeImageUtils.registerClassForReflection(access, MYSQL_SOCKET_CLASS); NativeImageUtils.registerConstructorsForReflection( - access, - "com.mysql.cj.conf.url.SingleConnectionUrl"); + access, "com.mysql.cj.conf.url.SingleConnectionUrl"); - NativeImageUtils.registerConstructorsForReflection( - access, - "com.mysql.cj.log.StandardLogger"); + NativeImageUtils.registerConstructorsForReflection(access, "com.mysql.cj.log.StandardLogger"); access.registerSubtypeReachabilityHandler( (duringAccess, exceptionClass) -> diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/OpenCensusFeature.java b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/OpenCensusFeature.java index 9b57671943..56e8dfd0a8 100644 --- a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/OpenCensusFeature.java +++ b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/OpenCensusFeature.java @@ -21,9 +21,7 @@ import com.oracle.svm.core.annotate.AutomaticFeature; import org.graalvm.nativeimage.hosted.Feature; -/** - * Registers reflection usage in OpenCensus libraries. - */ +/** Registers reflection usage in OpenCensus libraries. */ @AutomaticFeature final class OpenCensusFeature implements Feature { @@ -32,12 +30,9 @@ final class OpenCensusFeature implements Feature { @Override public void beforeAnalysis(BeforeAnalysisAccess access) { if (access.findClassByName(OPEN_CENSUS_CLASS) != null) { - registerForReflectiveInstantiation( - access, "io.opencensus.impl.metrics.MetricsComponentImpl"); - registerForReflectiveInstantiation( - access, "io.opencensus.impl.tags.TagsComponentImpl"); - registerForReflectiveInstantiation( - access, "io.opencensus.impl.trace.TraceComponentImpl"); + registerForReflectiveInstantiation(access, "io.opencensus.impl.metrics.MetricsComponentImpl"); + registerForReflectiveInstantiation(access, "io.opencensus.impl.tags.TagsComponentImpl"); + registerForReflectiveInstantiation(access, "io.opencensus.impl.trace.TraceComponentImpl"); } } } diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/SpannerFeature.java b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/SpannerFeature.java index b215bd7b23..025a16e5d7 100644 --- a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/SpannerFeature.java +++ b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/SpannerFeature.java @@ -22,9 +22,7 @@ import org.graalvm.nativeimage.ImageSingletons; import org.graalvm.nativeimage.hosted.Feature; -/** - * Registers Spanner library classes for reflection. - */ +/** Registers Spanner library classes for reflection. */ @AutomaticFeature final class SpannerFeature implements Feature { diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/ApiClientVersionSubstitutions.java b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/ApiClientVersionSubstitutions.java index d3fecb6183..a3affa6f56 100644 --- a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/ApiClientVersionSubstitutions.java +++ b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/ApiClientVersionSubstitutions.java @@ -21,17 +21,14 @@ import com.oracle.svm.core.annotate.TargetClass; import java.util.function.BooleanSupplier; -/** - * Substitution for setting Java version correctly in the Google Java Http Client. - */ +/** Substitution for setting Java version correctly in the Google Java Http Client. */ @TargetClass( className = "com.google.api.client.googleapis.services.AbstractGoogleClientRequest$ApiClientVersion", onlyWith = ApiClientVersionSubstitutions.OnlyIfInClassPath.class) final class ApiClientVersionSubstitutions { - @Alias - private String versionString; + @Alias private String versionString; @Substitute public String toString() { @@ -45,8 +42,7 @@ public String toString() { } } - private ApiClientVersionSubstitutions() { - } + private ApiClientVersionSubstitutions() {} static class OnlyIfInClassPath implements BooleanSupplier { diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/GaxPropertiesSubstitutions.java b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/GaxPropertiesSubstitutions.java index 9f30424b2b..0d79163a32 100644 --- a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/GaxPropertiesSubstitutions.java +++ b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/GaxPropertiesSubstitutions.java @@ -23,8 +23,8 @@ import java.util.function.BooleanSupplier; /** - * This file contains the GaxProperties substitution to correctly set the Java language string - * in API call headers for Native Image users. + * This file contains the GaxProperties substitution to correctly set the Java language string in + * API call headers for Native Image users. */ @TargetClass( className = "com.google.api.gax.core.GaxProperties", @@ -35,8 +35,7 @@ final class GaxPropertiesSubstitutions { @RecomputeFieldValue(kind = Kind.FromAlias) private static String JAVA_VERSION = System.getProperty("java.version") + "-graalvm"; - private GaxPropertiesSubstitutions() { - } + private GaxPropertiesSubstitutions() {} static class OnlyIfInClassPath implements BooleanSupplier { @@ -55,4 +54,3 @@ public boolean getAsBoolean() { } } } - diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/NettyInternalLoggerFactorySubstitutions.java b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/NettyInternalLoggerFactorySubstitutions.java index 63d9425999..336e06647a 100644 --- a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/NettyInternalLoggerFactorySubstitutions.java +++ b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/NettyInternalLoggerFactorySubstitutions.java @@ -23,13 +23,12 @@ import java.util.function.BooleanSupplier; /** - * Substitutions for {@link InternalLoggerFactory} which are needed to avoid dynamic loading - * of logging library. + * Substitutions for {@link InternalLoggerFactory} which are needed to avoid dynamic loading of + * logging library. */ @TargetClass( className = "io.grpc.netty.shaded.io.netty.util.internal.logging.InternalLoggerFactory", - onlyWith = NettyInternalLoggerFactorySubstitutions.OnlyIfInClassPath.class -) + onlyWith = NettyInternalLoggerFactorySubstitutions.OnlyIfInClassPath.class) final class NettyInternalLoggerFactorySubstitutions { @Substitute From a66ce61daff2fd1398c51f7090eec3d6e76640fa Mon Sep 17 00:00:00 2001 From: dzou Date: Mon, 29 Nov 2021 21:10:24 -0500 Subject: [PATCH 3/8] explicitly add dependencies --- google-cloud-core-native-support/pom.xml | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/google-cloud-core-native-support/pom.xml b/google-cloud-core-native-support/pom.xml index 340166761b..27efd76412 100644 --- a/google-cloud-core-native-support/pom.xml +++ b/google-cloud-core-native-support/pom.xml @@ -20,6 +20,17 @@ + + com.google.guava + guava + + + + io.grpc + grpc-netty-shaded + provided + + org.graalvm.nativeimage svm @@ -27,10 +38,9 @@ - io.grpc - grpc-netty-shaded + org.graalvm.sdk + graal-sdk provided - \ No newline at end of file From 5c1c4196941ee1b78b8a54baf22899ed00f9ce76 Mon Sep 17 00:00:00 2001 From: dzou Date: Wed, 12 Jan 2022 10:21:43 -0500 Subject: [PATCH 4/8] PR Comments, fix errors --- google-cloud-core-native-support/pom.xml | 10 ++-------- versions.txt | 3 ++- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/google-cloud-core-native-support/pom.xml b/google-cloud-core-native-support/pom.xml index 27efd76412..fcae790a59 100644 --- a/google-cloud-core-native-support/pom.xml +++ b/google-cloud-core-native-support/pom.xml @@ -6,13 +6,13 @@ 4.0.0 com.google.cloud google-cloud-core-native-support - 2.3.2-SNAPSHOT + 0.11.0-SNAPSHOT jar google-cloud-core-parent com.google.cloud - 2.3.2-SNAPSHOT + 2.3.2-SNAPSHOT @@ -36,11 +36,5 @@ svm provided - - - org.graalvm.sdk - graal-sdk - provided - \ No newline at end of file diff --git a/versions.txt b/versions.txt index dc34181bfa..980011d7de 100644 --- a/versions.txt +++ b/versions.txt @@ -1,4 +1,5 @@ # Format: # module:released-version:current-version -google-cloud-core:2.3.1:2.3.2-SNAPSHOT \ No newline at end of file +google-cloud-core:2.3.1:2.3.2-SNAPSHOT +google-cloud-core-native-support:0.10.0:0.11.0-SNAPSHOT \ No newline at end of file From a4e5c56a1e6668f37843ed745b75b2f3e3ac2aa2 Mon Sep 17 00:00:00 2001 From: dzou Date: Wed, 12 Jan 2022 10:23:21 -0500 Subject: [PATCH 5/8] update copyright --- .../cloud/nativeimage/features/GoogleJsonClientFeature.java | 2 +- .../com/google/cloud/nativeimage/features/GrpcNettyFeature.java | 2 +- .../com/google/cloud/nativeimage/features/NativeImageUtils.java | 2 +- .../cloud/nativeimage/features/ProtobufMessageFeature.java | 2 +- .../nativeimage/features/clients/CloudFunctionsFeature.java | 2 +- .../cloud/nativeimage/features/clients/CloudSqlFeature.java | 2 +- .../cloud/nativeimage/features/clients/OpenCensusFeature.java | 2 +- .../cloud/nativeimage/features/clients/SpannerFeature.java | 2 +- .../features/substitutions/ApiClientVersionSubstitutions.java | 2 +- .../features/substitutions/GaxPropertiesSubstitutions.java | 2 +- .../substitutions/NettyInternalLoggerFactorySubstitutions.java | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/GoogleJsonClientFeature.java b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/GoogleJsonClientFeature.java index 25a3e48336..8cc3107f4e 100644 --- a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/GoogleJsonClientFeature.java +++ b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/GoogleJsonClientFeature.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Google LLC + * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/GrpcNettyFeature.java b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/GrpcNettyFeature.java index 76dd724d8e..754f9005e2 100644 --- a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/GrpcNettyFeature.java +++ b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/GrpcNettyFeature.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Google LLC + * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/NativeImageUtils.java b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/NativeImageUtils.java index 21a501139b..8b19f4b84f 100644 --- a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/NativeImageUtils.java +++ b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/NativeImageUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Google LLC + * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/ProtobufMessageFeature.java b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/ProtobufMessageFeature.java index 92d82e064a..40251e85e4 100644 --- a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/ProtobufMessageFeature.java +++ b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/ProtobufMessageFeature.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Google LLC + * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/CloudFunctionsFeature.java b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/CloudFunctionsFeature.java index 1312f5ad37..7b7eaaebaf 100644 --- a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/CloudFunctionsFeature.java +++ b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/CloudFunctionsFeature.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Google LLC + * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/CloudSqlFeature.java b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/CloudSqlFeature.java index d8e3f89889..48b4c1e4ef 100644 --- a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/CloudSqlFeature.java +++ b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/CloudSqlFeature.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Google LLC + * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/OpenCensusFeature.java b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/OpenCensusFeature.java index 56e8dfd0a8..f2b6cb2098 100644 --- a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/OpenCensusFeature.java +++ b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/OpenCensusFeature.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Google LLC + * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/SpannerFeature.java b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/SpannerFeature.java index 025a16e5d7..e902c77928 100644 --- a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/SpannerFeature.java +++ b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/SpannerFeature.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Google LLC + * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/ApiClientVersionSubstitutions.java b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/ApiClientVersionSubstitutions.java index a3affa6f56..c170c2ea7a 100644 --- a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/ApiClientVersionSubstitutions.java +++ b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/ApiClientVersionSubstitutions.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Google LLC + * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/GaxPropertiesSubstitutions.java b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/GaxPropertiesSubstitutions.java index 0d79163a32..54245a8ee8 100644 --- a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/GaxPropertiesSubstitutions.java +++ b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/GaxPropertiesSubstitutions.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Google LLC + * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/NettyInternalLoggerFactorySubstitutions.java b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/NettyInternalLoggerFactorySubstitutions.java index 336e06647a..7fcea16318 100644 --- a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/NettyInternalLoggerFactorySubstitutions.java +++ b/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/NettyInternalLoggerFactorySubstitutions.java @@ -1,5 +1,5 @@ /* - * Copyright 2021 Google LLC + * Copyright 2022 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From 972234dce770767b7700f934b6e666fe8a912e91 Mon Sep 17 00:00:00 2001 From: dzou Date: Wed, 12 Jan 2022 10:30:50 -0500 Subject: [PATCH 6/8] resolve merge conflicts --- google-cloud-core-bom/pom.xml | 2 +- google-cloud-core-native-support/pom.xml | 2 +- pom.xml | 5 ----- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/google-cloud-core-bom/pom.xml b/google-cloud-core-bom/pom.xml index 28aa200487..70257984c2 100644 --- a/google-cloud-core-bom/pom.xml +++ b/google-cloud-core-bom/pom.xml @@ -78,7 +78,7 @@ com.google.cloud google-cloud-core-native-support - 2.3.2-SNAPSHOT + 0.11.0-SNAPSHOT diff --git a/google-cloud-core-native-support/pom.xml b/google-cloud-core-native-support/pom.xml index fcae790a59..b9a1957282 100644 --- a/google-cloud-core-native-support/pom.xml +++ b/google-cloud-core-native-support/pom.xml @@ -12,7 +12,7 @@ google-cloud-core-parent com.google.cloud - 2.3.2-SNAPSHOT + 2.3.6-SNAPSHOT diff --git a/pom.xml b/pom.xml index 6f2bf1e669..e2ac6d4f12 100644 --- a/pom.xml +++ b/pom.xml @@ -181,11 +181,6 @@ google-cloud-core ${project.version} - - com.google.cloud - google-cloud-core-native-support - ${project.version} - com.google.auth From e03c8ff0ac54695edf7c9c87edc024ebb70363e0 Mon Sep 17 00:00:00 2001 From: dzou Date: Wed, 12 Jan 2022 10:37:31 -0500 Subject: [PATCH 7/8] explicitly declare direct dependency --- google-cloud-core-native-support/pom.xml | 6 ++++++ pom.xml | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/google-cloud-core-native-support/pom.xml b/google-cloud-core-native-support/pom.xml index b9a1957282..cd846bd82e 100644 --- a/google-cloud-core-native-support/pom.xml +++ b/google-cloud-core-native-support/pom.xml @@ -36,5 +36,11 @@ svm provided + + + org.graalvm.sdk + graal-sdk + provided + \ No newline at end of file diff --git a/pom.xml b/pom.xml index e2ac6d4f12..10834acfb4 100644 --- a/pom.xml +++ b/pom.xml @@ -292,6 +292,13 @@ provided + + org.graalvm.sdk + graal-sdk + ${graalvm.version} + provided + + com.google.truth From ede16d29d2989f5a68de7d2873ab1ca49c5aaf7b Mon Sep 17 00:00:00 2001 From: dzou Date: Wed, 12 Jan 2022 11:33:26 -0500 Subject: [PATCH 8/8] rename artifact to same as existing. --- google-cloud-core-bom/pom.xml | 4 ++-- .../pom.xml | 5 +++-- .../cloud/nativeimage/features/GoogleJsonClientFeature.java | 0 .../google/cloud/nativeimage/features/GrpcNettyFeature.java | 0 .../google/cloud/nativeimage/features/NativeImageUtils.java | 0 .../cloud/nativeimage/features/ProtobufMessageFeature.java | 0 .../nativeimage/features/clients/CloudFunctionsFeature.java | 0 .../cloud/nativeimage/features/clients/CloudSqlFeature.java | 0 .../nativeimage/features/clients/OpenCensusFeature.java | 0 .../cloud/nativeimage/features/clients/SpannerFeature.java | 0 .../substitutions/ApiClientVersionSubstitutions.java | 0 .../features/substitutions/GaxPropertiesSubstitutions.java | 0 .../NettyInternalLoggerFactorySubstitutions.java | 0 .../google-cloud-core/native-image.properties | 0 .../com.google.cloud/google-cloud-core/resource-config.json | 0 pom.xml | 2 +- versions.txt | 2 +- 17 files changed, 7 insertions(+), 6 deletions(-) rename {google-cloud-core-native-support => native-image-support}/pom.xml (86%) rename {google-cloud-core-native-support => native-image-support}/src/main/java/com/google/cloud/nativeimage/features/GoogleJsonClientFeature.java (100%) rename {google-cloud-core-native-support => native-image-support}/src/main/java/com/google/cloud/nativeimage/features/GrpcNettyFeature.java (100%) rename {google-cloud-core-native-support => native-image-support}/src/main/java/com/google/cloud/nativeimage/features/NativeImageUtils.java (100%) rename {google-cloud-core-native-support => native-image-support}/src/main/java/com/google/cloud/nativeimage/features/ProtobufMessageFeature.java (100%) rename {google-cloud-core-native-support => native-image-support}/src/main/java/com/google/cloud/nativeimage/features/clients/CloudFunctionsFeature.java (100%) rename {google-cloud-core-native-support => native-image-support}/src/main/java/com/google/cloud/nativeimage/features/clients/CloudSqlFeature.java (100%) rename {google-cloud-core-native-support => native-image-support}/src/main/java/com/google/cloud/nativeimage/features/clients/OpenCensusFeature.java (100%) rename {google-cloud-core-native-support => native-image-support}/src/main/java/com/google/cloud/nativeimage/features/clients/SpannerFeature.java (100%) rename {google-cloud-core-native-support => native-image-support}/src/main/java/com/google/cloud/nativeimage/features/substitutions/ApiClientVersionSubstitutions.java (100%) rename {google-cloud-core-native-support => native-image-support}/src/main/java/com/google/cloud/nativeimage/features/substitutions/GaxPropertiesSubstitutions.java (100%) rename {google-cloud-core-native-support => native-image-support}/src/main/java/com/google/cloud/nativeimage/features/substitutions/NettyInternalLoggerFactorySubstitutions.java (100%) rename {google-cloud-core-native-support => native-image-support}/src/main/resources/META-INF/native-image/com.google.cloud/google-cloud-core/native-image.properties (100%) rename {google-cloud-core-native-support => native-image-support}/src/main/resources/META-INF/native-image/com.google.cloud/google-cloud-core/resource-config.json (100%) diff --git a/google-cloud-core-bom/pom.xml b/google-cloud-core-bom/pom.xml index 70257984c2..105abce31a 100644 --- a/google-cloud-core-bom/pom.xml +++ b/google-cloud-core-bom/pom.xml @@ -77,8 +77,8 @@ com.google.cloud - google-cloud-core-native-support - 0.11.0-SNAPSHOT + native-image-support + 0.11.0-SNAPSHOT diff --git a/google-cloud-core-native-support/pom.xml b/native-image-support/pom.xml similarity index 86% rename from google-cloud-core-native-support/pom.xml rename to native-image-support/pom.xml index cd846bd82e..fb74248dcb 100644 --- a/google-cloud-core-native-support/pom.xml +++ b/native-image-support/pom.xml @@ -4,9 +4,10 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 + Google Cloud Native Image Support com.google.cloud - google-cloud-core-native-support - 0.11.0-SNAPSHOT + native-image-support + 0.11.0-SNAPSHOT jar diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/GoogleJsonClientFeature.java b/native-image-support/src/main/java/com/google/cloud/nativeimage/features/GoogleJsonClientFeature.java similarity index 100% rename from google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/GoogleJsonClientFeature.java rename to native-image-support/src/main/java/com/google/cloud/nativeimage/features/GoogleJsonClientFeature.java diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/GrpcNettyFeature.java b/native-image-support/src/main/java/com/google/cloud/nativeimage/features/GrpcNettyFeature.java similarity index 100% rename from google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/GrpcNettyFeature.java rename to native-image-support/src/main/java/com/google/cloud/nativeimage/features/GrpcNettyFeature.java diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/NativeImageUtils.java b/native-image-support/src/main/java/com/google/cloud/nativeimage/features/NativeImageUtils.java similarity index 100% rename from google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/NativeImageUtils.java rename to native-image-support/src/main/java/com/google/cloud/nativeimage/features/NativeImageUtils.java diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/ProtobufMessageFeature.java b/native-image-support/src/main/java/com/google/cloud/nativeimage/features/ProtobufMessageFeature.java similarity index 100% rename from google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/ProtobufMessageFeature.java rename to native-image-support/src/main/java/com/google/cloud/nativeimage/features/ProtobufMessageFeature.java diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/CloudFunctionsFeature.java b/native-image-support/src/main/java/com/google/cloud/nativeimage/features/clients/CloudFunctionsFeature.java similarity index 100% rename from google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/CloudFunctionsFeature.java rename to native-image-support/src/main/java/com/google/cloud/nativeimage/features/clients/CloudFunctionsFeature.java diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/CloudSqlFeature.java b/native-image-support/src/main/java/com/google/cloud/nativeimage/features/clients/CloudSqlFeature.java similarity index 100% rename from google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/CloudSqlFeature.java rename to native-image-support/src/main/java/com/google/cloud/nativeimage/features/clients/CloudSqlFeature.java diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/OpenCensusFeature.java b/native-image-support/src/main/java/com/google/cloud/nativeimage/features/clients/OpenCensusFeature.java similarity index 100% rename from google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/OpenCensusFeature.java rename to native-image-support/src/main/java/com/google/cloud/nativeimage/features/clients/OpenCensusFeature.java diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/SpannerFeature.java b/native-image-support/src/main/java/com/google/cloud/nativeimage/features/clients/SpannerFeature.java similarity index 100% rename from google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/clients/SpannerFeature.java rename to native-image-support/src/main/java/com/google/cloud/nativeimage/features/clients/SpannerFeature.java diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/ApiClientVersionSubstitutions.java b/native-image-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/ApiClientVersionSubstitutions.java similarity index 100% rename from google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/ApiClientVersionSubstitutions.java rename to native-image-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/ApiClientVersionSubstitutions.java diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/GaxPropertiesSubstitutions.java b/native-image-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/GaxPropertiesSubstitutions.java similarity index 100% rename from google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/GaxPropertiesSubstitutions.java rename to native-image-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/GaxPropertiesSubstitutions.java diff --git a/google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/NettyInternalLoggerFactorySubstitutions.java b/native-image-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/NettyInternalLoggerFactorySubstitutions.java similarity index 100% rename from google-cloud-core-native-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/NettyInternalLoggerFactorySubstitutions.java rename to native-image-support/src/main/java/com/google/cloud/nativeimage/features/substitutions/NettyInternalLoggerFactorySubstitutions.java diff --git a/google-cloud-core-native-support/src/main/resources/META-INF/native-image/com.google.cloud/google-cloud-core/native-image.properties b/native-image-support/src/main/resources/META-INF/native-image/com.google.cloud/google-cloud-core/native-image.properties similarity index 100% rename from google-cloud-core-native-support/src/main/resources/META-INF/native-image/com.google.cloud/google-cloud-core/native-image.properties rename to native-image-support/src/main/resources/META-INF/native-image/com.google.cloud/google-cloud-core/native-image.properties diff --git a/google-cloud-core-native-support/src/main/resources/META-INF/native-image/com.google.cloud/google-cloud-core/resource-config.json b/native-image-support/src/main/resources/META-INF/native-image/com.google.cloud/google-cloud-core/resource-config.json similarity index 100% rename from google-cloud-core-native-support/src/main/resources/META-INF/native-image/com.google.cloud/google-cloud-core/resource-config.json rename to native-image-support/src/main/resources/META-INF/native-image/com.google.cloud/google-cloud-core/resource-config.json diff --git a/pom.xml b/pom.xml index 10834acfb4..66b0425521 100644 --- a/pom.xml +++ b/pom.xml @@ -338,7 +338,7 @@ google-cloud-core-http google-cloud-core-grpc google-cloud-core-bom - google-cloud-core-native-support + native-image-support diff --git a/versions.txt b/versions.txt index 5a41c2b58f..4cd1c2e1fd 100644 --- a/versions.txt +++ b/versions.txt @@ -2,4 +2,4 @@ # module:released-version:current-version google-cloud-core:2.3.5:2.3.6-SNAPSHOT -google-cloud-core-native-support:0.10.0:0.11.0-SNAPSHOT \ No newline at end of file +native-image-support:0.10.0:0.11.0-SNAPSHOT \ No newline at end of file