From e249c020639afbac44d7fc81a8179707f4b907d4 Mon Sep 17 00:00:00 2001 From: Valentin Kovalenko Date: Thu, 28 Mar 2024 09:08:14 -0600 Subject: [PATCH 01/16] Simplify the locations of `native-image.properties` JAVA-5219 --- .../native-image/{org.mongodb/bson => }/native-image.properties | 0 .../native-image/{org.mongodb/bson => }/native-image.properties | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename bson/src/main/resources/META-INF/native-image/{org.mongodb/bson => }/native-image.properties (100%) rename driver-core/src/main/resources/META-INF/native-image/{org.mongodb/bson => }/native-image.properties (100%) diff --git a/bson/src/main/resources/META-INF/native-image/org.mongodb/bson/native-image.properties b/bson/src/main/resources/META-INF/native-image/native-image.properties similarity index 100% rename from bson/src/main/resources/META-INF/native-image/org.mongodb/bson/native-image.properties rename to bson/src/main/resources/META-INF/native-image/native-image.properties diff --git a/driver-core/src/main/resources/META-INF/native-image/org.mongodb/bson/native-image.properties b/driver-core/src/main/resources/META-INF/native-image/native-image.properties similarity index 100% rename from driver-core/src/main/resources/META-INF/native-image/org.mongodb/bson/native-image.properties rename to driver-core/src/main/resources/META-INF/native-image/native-image.properties From 61c0127ba04e1de76ce3da78425f548b1787e25e Mon Sep 17 00:00:00 2001 From: Valentin Kovalenko Date: Thu, 28 Mar 2024 15:19:45 -0600 Subject: [PATCH 02/16] Update `DnsSpi` to check that `DnsClientProvider` is used JAVA-5219 --- .../mongodb/internal/dns/JndiDnsClient.java | 5 +- .../native-image/native-image.properties | 3 +- .../native-image/resource-config.json | 2 + .../graalvm/CustomDnsClientProvider.java | 61 +++++++++++++++++++ .../com/mongodb/internal/graalvm/DnsSpi.java | 27 +++++++- .../internal/graalvm/NativeImageApp.java | 18 ++++-- .../com.mongodb.spi.dns.DnsClientProvider | 1 + 7 files changed, 109 insertions(+), 8 deletions(-) create mode 100644 graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/CustomDnsClientProvider.java create mode 100644 graalvm-native-image-app/src/main/resources/META-INF/services/com.mongodb.spi.dns.DnsClientProvider diff --git a/driver-core/src/main/com/mongodb/internal/dns/JndiDnsClient.java b/driver-core/src/main/com/mongodb/internal/dns/JndiDnsClient.java index a1e95cac68a..71df713fb8b 100644 --- a/driver-core/src/main/com/mongodb/internal/dns/JndiDnsClient.java +++ b/driver-core/src/main/com/mongodb/internal/dns/JndiDnsClient.java @@ -32,7 +32,10 @@ import java.util.Hashtable; import java.util.List; -final class JndiDnsClient implements DnsClient { +/** + *

This class is not part of the public API and may be removed or changed at any time

+ */ +public final class JndiDnsClient implements DnsClient { @Override public List getResourceRecordData(final String name, final String type) throws DnsException { diff --git a/driver-core/src/main/resources/META-INF/native-image/native-image.properties b/driver-core/src/main/resources/META-INF/native-image/native-image.properties index 74579722773..49541a06e0e 100644 --- a/driver-core/src/main/resources/META-INF/native-image/native-image.properties +++ b/driver-core/src/main/resources/META-INF/native-image/native-image.properties @@ -18,4 +18,5 @@ Args =\ com.mongodb.UnixServerAddress,\ com.mongodb.internal.connection.SnappyCompressor,\ com.mongodb.internal.connection.ClientMetadataHelper,\ - com.mongodb.internal.connection.ServerAddressHelper + com.mongodb.internal.connection.ServerAddressHelper,\ + com.mongodb.internal.dns.DefaultDnsResolver diff --git a/driver-core/src/main/resources/META-INF/native-image/resource-config.json b/driver-core/src/main/resources/META-INF/native-image/resource-config.json index 8c008c9938d..43d3d5bb969 100644 --- a/driver-core/src/main/resources/META-INF/native-image/resource-config.json +++ b/driver-core/src/main/resources/META-INF/native-image/resource-config.json @@ -1,6 +1,8 @@ { "resources":{ "includes":[{ + "pattern":"\\QMETA-INF/services/com.mongodb.spi.dns.DnsClientProvider\\E" + }, { "pattern":"\\QMETA-INF/services/com.mongodb.spi.dns.InetAddressResolverProvider\\E" }]}, "bundles":[] diff --git a/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/CustomDnsClientProvider.java b/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/CustomDnsClientProvider.java new file mode 100644 index 00000000000..696d37becd0 --- /dev/null +++ b/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/CustomDnsClientProvider.java @@ -0,0 +1,61 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 + * + * http://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.mongodb.internal.graalvm; + +import com.mongodb.internal.dns.JndiDnsClient; +import com.mongodb.spi.dns.DnsClient; +import com.mongodb.spi.dns.DnsClientProvider; +import com.mongodb.spi.dns.DnsException; + +import java.util.List; + +import static java.lang.String.format; + +public final class CustomDnsClientProvider implements DnsClientProvider { + private static volatile boolean used = false; + + public CustomDnsClientProvider() { + } + + @Override + public DnsClient create() { + return new CustomDnsClient(); + } + + static void assertUsed() throws AssertionError { + if (!used) { + throw new AssertionError(format("%s is not used", CustomDnsClientProvider.class.getSimpleName())); + } + } + + private static void markUsed() { + used = true; + } + + private static final class CustomDnsClient implements DnsClient { + private final JndiDnsClient wrapped; + + CustomDnsClient() { + wrapped = new JndiDnsClient(); + } + + @Override + public List getResourceRecordData(final String name, final String type) throws DnsException { + markUsed(); + return wrapped.getResourceRecordData(name, type); + } + } +} diff --git a/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/DnsSpi.java b/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/DnsSpi.java index acfbb624629..7a234d72dbf 100644 --- a/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/DnsSpi.java +++ b/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/DnsSpi.java @@ -15,23 +15,46 @@ */ package com.mongodb.internal.graalvm; +import com.mongodb.MongoClientSettings; import com.mongodb.client.MongoClient; import com.mongodb.client.MongoClients; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; +import java.util.concurrent.TimeUnit; final class DnsSpi { private static final Logger LOGGER = LoggerFactory.getLogger(DnsSpi.class); public static void main(final String... args) { - LOGGER.info("Begin"); + useInetAddressResolverProvider(args); + useDnsClientProvider(); + } + + private static void useInetAddressResolverProvider(final String... args) { try (MongoClient client = args.length == 0 ? MongoClients.create() : MongoClients.create(args[0])) { LOGGER.info("Database names: {}", client.listDatabaseNames().into(new ArrayList<>())); } CustomInetAddressResolverProvider.assertUsed(); - LOGGER.info("End"); + } + + private static void useDnsClientProvider() { + try (MongoClient client = MongoClients.create(MongoClientSettings.builder() + .applyToClusterSettings(builder -> builder + .srvHost("a.b.c") + .serverSelectionTimeout(1, TimeUnit.MILLISECONDS)) + .build())) { + LOGGER.info("Database names: {}", client.listDatabaseNames().into(new ArrayList<>())); + } catch (RuntimeException e) { + try { + CustomDnsClientProvider.assertUsed(); + } catch (AssertionError err) { + err.addSuppressed(e); + throw err; + } + // an exception is expected provided that the assertion succeeds + } } private DnsSpi() { diff --git a/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/NativeImageApp.java b/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/NativeImageApp.java index 6c42ff21df3..afa7534b1b1 100644 --- a/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/NativeImageApp.java +++ b/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/NativeImageApp.java @@ -109,11 +109,21 @@ default Throwable runAndCatch() { final class Named implements ThrowingRunnable { private final String name; - private final ThrowingRunnable runnable; + private final ThrowingRunnable loggingRunnable; Named(final String name, final ThrowingRunnable runnable) { this.name = name; - this.runnable = runnable; + this.loggingRunnable = () -> { + LOGGER.info("Begin {}", name); + try { + runnable.run(); + } catch (Exception | AssertionError e) { + LOGGER.debug("Failure in " + name, e); + throw e; + } finally { + LOGGER.info("End {}", name); + } + }; } Named(final Class mainClass, final ThrowingRunnable runnable) { @@ -122,13 +132,13 @@ final class Named implements ThrowingRunnable { @Override public void run() throws Exception { - runnable.run(); + loggingRunnable.run(); } @Override @Nullable public Throwable runAndCatch() { - Throwable t = runnable.runAndCatch(); + Throwable t = loggingRunnable.runAndCatch(); if (t != null) { t = new AssertionError(name, t); } diff --git a/graalvm-native-image-app/src/main/resources/META-INF/services/com.mongodb.spi.dns.DnsClientProvider b/graalvm-native-image-app/src/main/resources/META-INF/services/com.mongodb.spi.dns.DnsClientProvider new file mode 100644 index 00000000000..4b53a569c91 --- /dev/null +++ b/graalvm-native-image-app/src/main/resources/META-INF/services/com.mongodb.spi.dns.DnsClientProvider @@ -0,0 +1 @@ +com.mongodb.internal.graalvm.CustomDnsClientProvider From f7ffe8a22d24fc7e7cca2e394cbc7950965fe9e3 Mon Sep 17 00:00:00 2001 From: Valentin Kovalenko Date: Thu, 28 Mar 2024 16:23:35 -0600 Subject: [PATCH 03/16] Move relevant reachability metadata into our JARs JAVA-5219 --- .../META-INF/native-image/reflect-config.json | 5 + .../META-INF/native-image/reflect-config.json | 5 + .../META-INF/native-image/reflect-config.json | 5 + .../META-INF/native-image/jni-config.json | 22 ++++ .../META-INF/native-image/reflect-config.json | 96 ++++++++++++++++ .../native-image/resource-config.json | 26 +++++ .../META-INF/native-image/jni-config.json | 22 +--- .../META-INF/native-image/reflect-config.json | 105 +----------------- .../native-image/resource-config.json | 26 ----- 9 files changed, 161 insertions(+), 151 deletions(-) create mode 100644 bson-kotlin/src/main/resources/META-INF/native-image/reflect-config.json create mode 100644 bson-kotlinx/src/main/resources/META-INF/native-image/reflect-config.json create mode 100644 bson-record-codec/src/main/resources/META-INF/native-image/reflect-config.json create mode 100644 driver-core/src/main/resources/META-INF/native-image/jni-config.json create mode 100644 driver-core/src/main/resources/META-INF/native-image/reflect-config.json diff --git a/bson-kotlin/src/main/resources/META-INF/native-image/reflect-config.json b/bson-kotlin/src/main/resources/META-INF/native-image/reflect-config.json new file mode 100644 index 00000000000..fc407c928bf --- /dev/null +++ b/bson-kotlin/src/main/resources/META-INF/native-image/reflect-config.json @@ -0,0 +1,5 @@ +[ +{ + "name":"org.bson.codecs.kotlin.DataClassCodecProvider" +} +] diff --git a/bson-kotlinx/src/main/resources/META-INF/native-image/reflect-config.json b/bson-kotlinx/src/main/resources/META-INF/native-image/reflect-config.json new file mode 100644 index 00000000000..48b9c16c1a7 --- /dev/null +++ b/bson-kotlinx/src/main/resources/META-INF/native-image/reflect-config.json @@ -0,0 +1,5 @@ +[ +{ + "name":"org.bson.codecs.kotlinx.KotlinSerializerCodecProvider" +} +] diff --git a/bson-record-codec/src/main/resources/META-INF/native-image/reflect-config.json b/bson-record-codec/src/main/resources/META-INF/native-image/reflect-config.json new file mode 100644 index 00000000000..d320243b4e7 --- /dev/null +++ b/bson-record-codec/src/main/resources/META-INF/native-image/reflect-config.json @@ -0,0 +1,5 @@ +[ +{ + "name":"org.bson.codecs.record.RecordCodecProvider" +} +] diff --git a/driver-core/src/main/resources/META-INF/native-image/jni-config.json b/driver-core/src/main/resources/META-INF/native-image/jni-config.json new file mode 100644 index 00000000000..ef5ea8e42da --- /dev/null +++ b/driver-core/src/main/resources/META-INF/native-image/jni-config.json @@ -0,0 +1,22 @@ +[ +{ + "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_crypto_fn", + "methods":[{"name":"crypt","parameterTypes":["com.sun.jna.Pointer","com.mongodb.crypt.capi.CAPI$mongocrypt_binary_t","com.mongodb.crypt.capi.CAPI$mongocrypt_binary_t","com.mongodb.crypt.capi.CAPI$mongocrypt_binary_t","com.mongodb.crypt.capi.CAPI$mongocrypt_binary_t","com.sun.jna.Pointer","com.mongodb.crypt.capi.CAPI$mongocrypt_status_t"] }] +}, +{ + "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_hash_fn", + "methods":[{"name":"hash","parameterTypes":["com.sun.jna.Pointer","com.mongodb.crypt.capi.CAPI$mongocrypt_binary_t","com.mongodb.crypt.capi.CAPI$mongocrypt_binary_t","com.mongodb.crypt.capi.CAPI$mongocrypt_status_t"] }] +}, +{ + "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_hmac_fn", + "methods":[{"name":"hmac","parameterTypes":["com.sun.jna.Pointer","com.mongodb.crypt.capi.CAPI$mongocrypt_binary_t","com.mongodb.crypt.capi.CAPI$mongocrypt_binary_t","com.mongodb.crypt.capi.CAPI$mongocrypt_binary_t","com.mongodb.crypt.capi.CAPI$mongocrypt_status_t"] }] +}, +{ + "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_log_fn_t", + "methods":[{"name":"log","parameterTypes":["int","com.mongodb.crypt.capi.CAPI$cstring","int","com.sun.jna.Pointer"] }] +}, +{ + "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_random_fn", + "methods":[{"name":"random","parameterTypes":["com.sun.jna.Pointer","com.mongodb.crypt.capi.CAPI$mongocrypt_binary_t","int","com.mongodb.crypt.capi.CAPI$mongocrypt_status_t"] }] +} +] diff --git a/driver-core/src/main/resources/META-INF/native-image/reflect-config.json b/driver-core/src/main/resources/META-INF/native-image/reflect-config.json new file mode 100644 index 00000000000..c326eb751bf --- /dev/null +++ b/driver-core/src/main/resources/META-INF/native-image/reflect-config.json @@ -0,0 +1,96 @@ +[ +{ + "name":"com.mongodb.BasicDBObject", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.mongodb.MongoNamespace", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true +}, +{ + "name":"com.mongodb.WriteConcern", + "allPublicFields":true +}, +{ + "name":"com.mongodb.client.model.changestream.ChangeStreamDocument", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":["java.lang.String","org.bson.BsonDocument","org.bson.BsonDocument","org.bson.BsonDocument","java.lang.Object","java.lang.Object","org.bson.BsonDocument","org.bson.BsonTimestamp","com.mongodb.client.model.changestream.UpdateDescription","org.bson.BsonInt64","org.bson.BsonDocument","org.bson.BsonDateTime","com.mongodb.client.model.changestream.SplitEvent","org.bson.BsonDocument"] }] +}, +{ + "name":"com.mongodb.client.model.changestream.SplitEvent", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true +}, +{ + "name":"com.mongodb.client.model.changestream.TruncatedArray", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true +}, +{ + "name":"com.mongodb.client.model.changestream.UpdateDescription", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true, + "methods":[{"name":"","parameterTypes":["java.util.List","org.bson.BsonDocument","java.util.List","org.bson.BsonDocument"] }] +}, +{ + "name":"com.mongodb.crypt.capi.CAPI", + "allPublicFields":true, + "queryAllDeclaredMethods":true +}, +{ + "name":"com.mongodb.crypt.capi.CAPI$cstring", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_binary_t", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_crypto_fn", + "queryAllDeclaredMethods":true, + "queryAllPublicMethods":true +}, +{ + "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_ctx_t", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_hash_fn", + "queryAllDeclaredMethods":true, + "queryAllPublicMethods":true +}, +{ + "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_hmac_fn", + "queryAllDeclaredMethods":true, + "queryAllPublicMethods":true +}, +{ + "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_kms_ctx_t", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_log_fn_t", + "queryAllDeclaredMethods":true, + "queryAllPublicMethods":true +}, +{ + "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_random_fn", + "queryAllDeclaredMethods":true, + "queryAllPublicMethods":true +}, +{ + "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_status_t", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_t", + "methods":[{"name":"","parameterTypes":[] }] +} +] diff --git a/driver-core/src/main/resources/META-INF/native-image/resource-config.json b/driver-core/src/main/resources/META-INF/native-image/resource-config.json index 43d3d5bb969..84fac027a25 100644 --- a/driver-core/src/main/resources/META-INF/native-image/resource-config.json +++ b/driver-core/src/main/resources/META-INF/native-image/resource-config.json @@ -4,6 +4,32 @@ "pattern":"\\QMETA-INF/services/com.mongodb.spi.dns.DnsClientProvider\\E" }, { "pattern":"\\QMETA-INF/services/com.mongodb.spi.dns.InetAddressResolverProvider\\E" + }, { + "pattern":"\\Qcom/sun/jna/darwin-aarch64/libjnidispatch.jnilib\\E" + }, { + "pattern":"\\Qcom/sun/jna/darwin-x86-64/libjnidispatch.jnilib\\E" + }, { + "pattern":"\\Qcom/sun/jna/linux-aarch64/libjnidispatch.so\\E" + }, { + "pattern":"\\Qcom/sun/jna/linux-ppc64le/libjnidispatch.so\\E" + }, { + "pattern":"\\Qcom/sun/jna/linux-s390x/libjnidispatch.so\\E" + }, { + "pattern":"\\Qcom/sun/jna/linux-x86-64/libjnidispatch.so\\E" + }, { + "pattern":"\\Qcom/sun/jna/win32-x86-64/jnidispatch.dll\\E" + }, { + "pattern":"\\Qdarwin/libmongocrypt.dylib\\E" + }, { + "pattern":"\\Qlinux-aarch64/libmongocrypt.so\\E" + }, { + "pattern":"\\Qlinux-ppc64le/libmongocrypt.so\\E" + }, { + "pattern":"\\Qlinux-s390x/libmongocrypt.so\\E" + }, { + "pattern":"\\Qlinux-x86-64/libmongocrypt.so\\E" + }, { + "pattern":"\\Qwin32-x86-64/mongocrypt.dll\\E" }]}, "bundles":[] } diff --git a/graalvm-native-image-app/src/main/resources/META-INF/native-image/jni-config.json b/graalvm-native-image-app/src/main/resources/META-INF/native-image/jni-config.json index c1dcb7f2ded..1d3533f349b 100644 --- a/graalvm-native-image-app/src/main/resources/META-INF/native-image/jni-config.json +++ b/graalvm-native-image-app/src/main/resources/META-INF/native-image/jni-config.json @@ -1,24 +1,4 @@ [ -{ - "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_crypto_fn", - "methods":[{"name":"crypt","parameterTypes":["com.sun.jna.Pointer","com.mongodb.crypt.capi.CAPI$mongocrypt_binary_t","com.mongodb.crypt.capi.CAPI$mongocrypt_binary_t","com.mongodb.crypt.capi.CAPI$mongocrypt_binary_t","com.mongodb.crypt.capi.CAPI$mongocrypt_binary_t","com.sun.jna.Pointer","com.mongodb.crypt.capi.CAPI$mongocrypt_status_t"] }] -}, -{ - "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_hash_fn", - "methods":[{"name":"hash","parameterTypes":["com.sun.jna.Pointer","com.mongodb.crypt.capi.CAPI$mongocrypt_binary_t","com.mongodb.crypt.capi.CAPI$mongocrypt_binary_t","com.mongodb.crypt.capi.CAPI$mongocrypt_status_t"] }] -}, -{ - "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_hmac_fn", - "methods":[{"name":"hmac","parameterTypes":["com.sun.jna.Pointer","com.mongodb.crypt.capi.CAPI$mongocrypt_binary_t","com.mongodb.crypt.capi.CAPI$mongocrypt_binary_t","com.mongodb.crypt.capi.CAPI$mongocrypt_binary_t","com.mongodb.crypt.capi.CAPI$mongocrypt_status_t"] }] -}, -{ - "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_log_fn_t", - "methods":[{"name":"log","parameterTypes":["int","com.mongodb.crypt.capi.CAPI$cstring","int","com.sun.jna.Pointer"] }] -}, -{ - "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_random_fn", - "methods":[{"name":"random","parameterTypes":["com.sun.jna.Pointer","com.mongodb.crypt.capi.CAPI$mongocrypt_binary_t","int","com.mongodb.crypt.capi.CAPI$mongocrypt_status_t"] }] -}, { "name":"com.mongodb.internal.graalvm.NativeImageApp", "methods":[{"name":"main","parameterTypes":["java.lang.String[]"] }] @@ -181,4 +161,4 @@ "name":"java.nio.ShortBuffer", "methods":[{"name":"array","parameterTypes":[] }, {"name":"arrayOffset","parameterTypes":[] }] } -] \ No newline at end of file +] diff --git a/graalvm-native-image-app/src/main/resources/META-INF/native-image/reflect-config.json b/graalvm-native-image-app/src/main/resources/META-INF/native-image/reflect-config.json index 29ded3e5f40..4b32b61c781 100644 --- a/graalvm-native-image-app/src/main/resources/META-INF/native-image/reflect-config.json +++ b/graalvm-native-image-app/src/main/resources/META-INF/native-image/reflect-config.json @@ -65,100 +65,6 @@ "name":"ch.qos.logback.core.spi.ContextAware", "methods":[{"name":"valueOf","parameterTypes":["java.lang.String"] }] }, -{ - "name":"com.mongodb.BasicDBObject", - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"com.mongodb.MongoNamespace", - "allDeclaredFields":true, - "queryAllDeclaredMethods":true, - "queryAllDeclaredConstructors":true -}, -{ - "name":"com.mongodb.WriteConcern", - "allPublicFields":true -}, -{ - "name":"com.mongodb.client.model.changestream.ChangeStreamDocument", - "allDeclaredFields":true, - "queryAllDeclaredMethods":true, - "queryAllDeclaredConstructors":true, - "methods":[{"name":"","parameterTypes":["java.lang.String","org.bson.BsonDocument","org.bson.BsonDocument","org.bson.BsonDocument","java.lang.Object","java.lang.Object","org.bson.BsonDocument","org.bson.BsonTimestamp","com.mongodb.client.model.changestream.UpdateDescription","org.bson.BsonInt64","org.bson.BsonDocument","org.bson.BsonDateTime","com.mongodb.client.model.changestream.SplitEvent","org.bson.BsonDocument"] }] -}, -{ - "name":"com.mongodb.client.model.changestream.SplitEvent", - "allDeclaredFields":true, - "queryAllDeclaredMethods":true, - "queryAllDeclaredConstructors":true -}, -{ - "name":"com.mongodb.client.model.changestream.TruncatedArray", - "allDeclaredFields":true, - "queryAllDeclaredMethods":true, - "queryAllDeclaredConstructors":true -}, -{ - "name":"com.mongodb.client.model.changestream.UpdateDescription", - "allDeclaredFields":true, - "queryAllDeclaredMethods":true, - "queryAllDeclaredConstructors":true, - "methods":[{"name":"","parameterTypes":["java.util.List","org.bson.BsonDocument","java.util.List","org.bson.BsonDocument"] }] -}, -{ - "name":"com.mongodb.crypt.capi.CAPI", - "allPublicFields":true, - "queryAllDeclaredMethods":true -}, -{ - "name":"com.mongodb.crypt.capi.CAPI$cstring", - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_binary_t", - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_crypto_fn", - "queryAllDeclaredMethods":true, - "queryAllPublicMethods":true -}, -{ - "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_ctx_t", - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_hash_fn", - "queryAllDeclaredMethods":true, - "queryAllPublicMethods":true -}, -{ - "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_hmac_fn", - "queryAllDeclaredMethods":true, - "queryAllPublicMethods":true -}, -{ - "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_kms_ctx_t", - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_log_fn_t", - "queryAllDeclaredMethods":true, - "queryAllPublicMethods":true -}, -{ - "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_random_fn", - "queryAllDeclaredMethods":true, - "queryAllPublicMethods":true -}, -{ - "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_status_t", - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_t", - "methods":[{"name":"","parameterTypes":[] }] -}, { "name":"com.sun.crypto.provider.AESCipher$General", "methods":[{"name":"","parameterTypes":[] }] @@ -287,15 +193,6 @@ "name":"long", "fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}] }, -{ - "name":"org.bson.codecs.kotlin.DataClassCodecProvider" -}, -{ - "name":"org.bson.codecs.kotlinx.KotlinSerializerCodecProvider" -}, -{ - "name":"org.bson.codecs.record.RecordCodecProvider" -}, { "name":"org.slf4j.Logger" }, @@ -443,4 +340,4 @@ "name":"void", "fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}] } -] \ No newline at end of file +] diff --git a/graalvm-native-image-app/src/main/resources/META-INF/native-image/resource-config.json b/graalvm-native-image-app/src/main/resources/META-INF/native-image/resource-config.json index ece741c68e4..3099bc884c0 100644 --- a/graalvm-native-image-app/src/main/resources/META-INF/native-image/resource-config.json +++ b/graalvm-native-image-app/src/main/resources/META-INF/native-image/resource-config.json @@ -18,32 +18,6 @@ "pattern":"\\QMETA-INF/services/javax.xml.parsers.SAXParserFactory\\E" }, { "pattern":"\\QMETA-INF/services/org.slf4j.spi.SLF4JServiceProvider\\E" - }, { - "pattern":"\\Qcom/sun/jna/darwin-aarch64/libjnidispatch.jnilib\\E" - }, { - "pattern":"\\Qcom/sun/jna/darwin-x86-64/libjnidispatch.jnilib\\E" - }, { - "pattern":"\\Qcom/sun/jna/linux-aarch64/libjnidispatch.so\\E" - }, { - "pattern":"\\Qcom/sun/jna/linux-ppc64le/libjnidispatch.so\\E" - }, { - "pattern":"\\Qcom/sun/jna/linux-s390x/libjnidispatch.so\\E" - }, { - "pattern":"\\Qcom/sun/jna/linux-x86-64/libjnidispatch.so\\E" - }, { - "pattern":"\\Qcom/sun/jna/win32-x86-64/jnidispatch.dll\\E" - }, { - "pattern":"\\Qdarwin/libmongocrypt.dylib\\E" - }, { - "pattern":"\\Qlinux-aarch64/libmongocrypt.so\\E" - }, { - "pattern":"\\Qlinux-ppc64le/libmongocrypt.so\\E" - }, { - "pattern":"\\Qlinux-s390x/libmongocrypt.so\\E" - }, { - "pattern":"\\Qlinux-x86-64/libmongocrypt.so\\E" - }, { - "pattern":"\\Qwin32-x86-64/mongocrypt.dll\\E" }, { "pattern":"\\Qlogback-test.scmo\\E" }, { From db998ac4396af6de4a6c8ecdae5f3cdf65af72b1 Mon Sep 17 00:00:00 2001 From: Valentin Kovalenko Date: Tue, 2 Apr 2024 20:39:43 -0600 Subject: [PATCH 04/16] Add GraalVM substitutions THe added substitutions are based on https://github.com/quarkusio/quarkus/blob/main/extensions/mongodb-client/runtime/src/main/java/io/quarkus/mongodb/runtime/graal/MongoClientSubstitutions.java JAVA-5219 --- build.gradle | 1 + config/spotbugs/exclude.xml | 4 ++ driver-core/build.gradle | 2 + .../src/main/com/mongodb/MongoCompressor.java | 2 + .../main/com/mongodb/UnixServerAddress.java | 2 + .../connection/SocketStreamFactory.java | 11 +++++ .../MongoCompressorSubstitution.java | 31 +++++++++++++ .../SocketStreamFactorySubstitution.java | 45 +++++++++++++++++++ .../graalvm/substitution/Substitutions.java | 37 +++++++++++++++ .../SubstitutionsSubstitution.java | 29 ++++++++++++ graalvm-native-image-app/build.gradle | 1 + .../internal/graalvm/NativeImageApp.java | 3 ++ 12 files changed, 168 insertions(+) create mode 100644 driver-core/src/main/com/mongodb/internal/graalvm/substitution/MongoCompressorSubstitution.java create mode 100644 driver-core/src/main/com/mongodb/internal/graalvm/substitution/SocketStreamFactorySubstitution.java create mode 100644 driver-core/src/main/com/mongodb/internal/graalvm/substitution/Substitutions.java create mode 100644 driver-core/src/main/com/mongodb/internal/graalvm/substitution/SubstitutionsSubstitution.java diff --git a/build.gradle b/build.gradle index b1353375a38..efee96e00bf 100644 --- a/build.gradle +++ b/build.gradle @@ -58,6 +58,7 @@ ext { mongoCryptVersion = '1.8.0' projectReactorVersion = '2022.0.0' junitBomVersion = '5.8.2' + graalSdkVersion = '24.0.0' gitVersion = getGitVersion() } diff --git a/config/spotbugs/exclude.xml b/config/spotbugs/exclude.xml index d35f0a81c8a..28f50a725eb 100644 --- a/config/spotbugs/exclude.xml +++ b/config/spotbugs/exclude.xml @@ -276,5 +276,9 @@ + + + + diff --git a/driver-core/build.gradle b/driver-core/build.gradle index 40a63c15d49..2edf69d7133 100644 --- a/driver-core/build.gradle +++ b/driver-core/build.gradle @@ -45,6 +45,8 @@ dependencies { api "io.netty:netty-buffer", optional api "io.netty:netty-transport", optional api "io.netty:netty-handler", optional + compileOnly "org.graalvm.sdk:nativeimage:$graalSdkVersion" + compileOnly "org.graalvm.sdk:graal-sdk:$graalSdkVersion" // Optionally depend on both AWS SDK v2 and v1. The driver will use v2 is present, v1 if present, or built-in functionality if // neither are present diff --git a/driver-core/src/main/com/mongodb/MongoCompressor.java b/driver-core/src/main/com/mongodb/MongoCompressor.java index 57f88716d89..4c9d866979a 100644 --- a/driver-core/src/main/com/mongodb/MongoCompressor.java +++ b/driver-core/src/main/com/mongodb/MongoCompressor.java @@ -16,6 +16,7 @@ package com.mongodb; +import com.mongodb.internal.graalvm.substitution.MongoCompressorSubstitution; import com.mongodb.lang.Nullable; import java.util.Collections; @@ -46,6 +47,7 @@ public final class MongoCompressor { * * @return A compressor based on the snappy compression algorithm * @mongodb.server.release 3.4 + * @throws UnsupportedOperationException If {@linkplain MongoCompressorSubstitution#createSnappyCompressor() called in a GraalVM native image}. */ public static MongoCompressor createSnappyCompressor() { return new MongoCompressor("snappy"); diff --git a/driver-core/src/main/com/mongodb/UnixServerAddress.java b/driver-core/src/main/com/mongodb/UnixServerAddress.java index bba882de794..c34ccdb74f1 100644 --- a/driver-core/src/main/com/mongodb/UnixServerAddress.java +++ b/driver-core/src/main/com/mongodb/UnixServerAddress.java @@ -17,12 +17,14 @@ package com.mongodb; import com.mongodb.annotations.Immutable; +import com.mongodb.internal.graalvm.substitution.SocketStreamFactorySubstitution; import static com.mongodb.assertions.Assertions.isTrueArgument; import static com.mongodb.assertions.Assertions.notNull; /** * Represents the location of a MongoD unix domain socket. + * It is {@linkplain SocketStreamFactorySubstitution#create(ServerAddress) not supported in GraalVM native image}. * *

Requires the 'jnr.unixsocket' library.

* @since 3.7 diff --git a/driver-core/src/main/com/mongodb/internal/connection/SocketStreamFactory.java b/driver-core/src/main/com/mongodb/internal/connection/SocketStreamFactory.java index 793fc8b3dc4..2b50f29332a 100644 --- a/driver-core/src/main/com/mongodb/internal/connection/SocketStreamFactory.java +++ b/driver-core/src/main/com/mongodb/internal/connection/SocketStreamFactory.java @@ -21,6 +21,7 @@ import com.mongodb.UnixServerAddress; import com.mongodb.connection.SocketSettings; import com.mongodb.connection.SslSettings; +import com.mongodb.internal.graalvm.substitution.SocketStreamFactorySubstitution; import com.mongodb.spi.dns.InetAddressResolver; import javax.net.SocketFactory; @@ -53,8 +54,18 @@ public SocketStreamFactory(final InetAddressResolver inetAddressResolver, final this.sslSettings = notNull("sslSettings", sslSettings); } + /** + * @see SocketStreamFactorySubstitution#create(ServerAddress) + */ @Override public Stream create(final ServerAddress serverAddress) { + return createInternal(serverAddress); + } + + /** + * @see SocketStreamFactorySubstitution#create(ServerAddress) + */ + private Stream createInternal(final ServerAddress serverAddress) { Stream stream; if (serverAddress instanceof UnixServerAddress) { if (sslSettings.isEnabled()) { diff --git a/driver-core/src/main/com/mongodb/internal/graalvm/substitution/MongoCompressorSubstitution.java b/driver-core/src/main/com/mongodb/internal/graalvm/substitution/MongoCompressorSubstitution.java new file mode 100644 index 00000000000..36694ab8ef8 --- /dev/null +++ b/driver-core/src/main/com/mongodb/internal/graalvm/substitution/MongoCompressorSubstitution.java @@ -0,0 +1,31 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 + * + * http://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.mongodb.internal.graalvm.substitution; + +import com.mongodb.MongoCompressor; +import com.oracle.svm.core.annotate.Substitute; +import com.oracle.svm.core.annotate.TargetClass; + +@TargetClass(MongoCompressor.class) +public final class MongoCompressorSubstitution { + @Substitute + public static MongoCompressor createSnappyCompressor() { + throw new UnsupportedOperationException("Snappy compressor is not supported in GraalVM native image"); + } + + private MongoCompressorSubstitution() { + } +} diff --git a/driver-core/src/main/com/mongodb/internal/graalvm/substitution/SocketStreamFactorySubstitution.java b/driver-core/src/main/com/mongodb/internal/graalvm/substitution/SocketStreamFactorySubstitution.java new file mode 100644 index 00000000000..581bedff490 --- /dev/null +++ b/driver-core/src/main/com/mongodb/internal/graalvm/substitution/SocketStreamFactorySubstitution.java @@ -0,0 +1,45 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 + * + * http://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.mongodb.internal.graalvm.substitution; + +import com.mongodb.ServerAddress; +import com.mongodb.UnixServerAddress; +import com.mongodb.internal.connection.SocketStreamFactory; +import com.mongodb.internal.connection.Stream; +import com.oracle.svm.core.annotate.Alias; +import com.oracle.svm.core.annotate.Substitute; +import com.oracle.svm.core.annotate.TargetClass; + +import static com.mongodb.assertions.Assertions.fail; + +@TargetClass(SocketStreamFactory.class) +public final class SocketStreamFactorySubstitution { + @Substitute + public Stream create(final ServerAddress serverAddress) { + if (serverAddress instanceof UnixServerAddress) { + throw new UnsupportedOperationException("UnixServerAddress is not supported in GraalVM native image"); + } + return createInternal(serverAddress); + } + + @Alias + private Stream createInternal(final ServerAddress serverAddress) { + throw fail(); + } + + private SocketStreamFactorySubstitution() { + } +} diff --git a/driver-core/src/main/com/mongodb/internal/graalvm/substitution/Substitutions.java b/driver-core/src/main/com/mongodb/internal/graalvm/substitution/Substitutions.java new file mode 100644 index 00000000000..f4cea7f33ad --- /dev/null +++ b/driver-core/src/main/com/mongodb/internal/graalvm/substitution/Substitutions.java @@ -0,0 +1,37 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 + * + * http://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.mongodb.internal.graalvm.substitution; + +import org.graalvm.nativeimage.ImageInfo; + +import static com.mongodb.assertions.Assertions.fail; + +public final class Substitutions { + /** + * @throws AssertionError If called at native image run time, + * unless the method body is substituted using the GraalVM native image technology. + * If not called at native image run time, then does not throw. + * @see SubstitutionsSubstitution#assertUsed() + */ + public static void assertUsed() throws AssertionError { + if (ImageInfo.inImageRuntimeCode()) { + fail("The body of this method must be substituted when compiling using the GraalVM native image technology"); + } + } + + private Substitutions() { + } +} diff --git a/driver-core/src/main/com/mongodb/internal/graalvm/substitution/SubstitutionsSubstitution.java b/driver-core/src/main/com/mongodb/internal/graalvm/substitution/SubstitutionsSubstitution.java new file mode 100644 index 00000000000..bd5dae5e863 --- /dev/null +++ b/driver-core/src/main/com/mongodb/internal/graalvm/substitution/SubstitutionsSubstitution.java @@ -0,0 +1,29 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 + * + * http://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.mongodb.internal.graalvm.substitution; + +import com.oracle.svm.core.annotate.Substitute; +import com.oracle.svm.core.annotate.TargetClass; + +@TargetClass(Substitutions.class) +final class SubstitutionsSubstitution { + @Substitute + public static void assertUsed() { + } + + private SubstitutionsSubstitution() { + } +} diff --git a/graalvm-native-image-app/build.gradle b/graalvm-native-image-app/build.gradle index abb5ffda3a2..baf28986464 100644 --- a/graalvm-native-image-app/build.gradle +++ b/graalvm-native-image-app/build.gradle @@ -92,4 +92,5 @@ dependencies { implementation 'ch.qos.logback:logback-classic:1.5.3' implementation platform("io.projectreactor:reactor-bom:$projectReactorVersion") implementation 'io.projectreactor:reactor-core' + implementation "org.graalvm.sdk:nativeimage:$graalSdkVersion" } diff --git a/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/NativeImageApp.java b/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/NativeImageApp.java index afa7534b1b1..034d20f6a25 100644 --- a/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/NativeImageApp.java +++ b/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/NativeImageApp.java @@ -15,6 +15,7 @@ */ package com.mongodb.internal.graalvm; +import com.mongodb.internal.graalvm.substitution.Substitutions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,6 +36,8 @@ public static void main(final String[] args) { String[] arguments = new String[] {getConnectionStringSystemPropertyOrDefault()}; LOGGER.info("proper args={}, tour/example arguments={}", Arrays.toString(args), Arrays.toString(arguments)); List errors = Stream.of( + new ThrowingRunnable.Named("GraalVM native image substitutions", + Substitutions::assertUsed), new ThrowingRunnable.Named(DnsSpi.class, () -> DnsSpi.main(arguments)), new ThrowingRunnable.Named(gridfs.GridFSTour.class, From 92ac5ae3d0c3b8f20862094916081b5d83de3c32 Mon Sep 17 00:00:00 2001 From: Valentin Kovalenko Date: Wed, 3 Apr 2024 08:10:13 -0600 Subject: [PATCH 05/16] Use parameterized logging when logging an exception JAVA-5219 --- .../src/main/com/mongodb/internal/graalvm/NativeImageApp.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/NativeImageApp.java b/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/NativeImageApp.java index 034d20f6a25..5803fccf398 100644 --- a/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/NativeImageApp.java +++ b/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/NativeImageApp.java @@ -121,7 +121,7 @@ final class Named implements ThrowingRunnable { try { runnable.run(); } catch (Exception | AssertionError e) { - LOGGER.debug("Failure in " + name, e); + LOGGER.debug("Failure in {}", name, e); throw e; } finally { LOGGER.info("End {}", name); From 7b10c600c1842097ae6053938ba8629591b28363 Mon Sep 17 00:00:00 2001 From: Valentin Kovalenko Date: Wed, 3 Apr 2024 11:44:24 -0600 Subject: [PATCH 06/16] Alleviate the race condition in `DnsSpi.useDnsClientProvider` JAVA-5219 --- .../src/main/com/mongodb/internal/graalvm/DnsSpi.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/DnsSpi.java b/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/DnsSpi.java index 7a234d72dbf..f3a78d4cabe 100644 --- a/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/DnsSpi.java +++ b/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/DnsSpi.java @@ -43,7 +43,11 @@ private static void useDnsClientProvider() { try (MongoClient client = MongoClients.create(MongoClientSettings.builder() .applyToClusterSettings(builder -> builder .srvHost("a.b.c") - .serverSelectionTimeout(1, TimeUnit.MILLISECONDS)) + // `MongoClient` uses `CustomDnsClientProvider` asynchronously, + // and by waiting for server selection that cannot succeed due to `a.b.c` not resolving to an IP address, + // we give `MongoClient` enough time to use `CustomDnsClientProvider`. + // This is a tolerable race condition for a test. + .serverSelectionTimeout(2, TimeUnit.SECONDS)) .build())) { LOGGER.info("Database names: {}", client.listDatabaseNames().into(new ArrayList<>())); } catch (RuntimeException e) { @@ -53,7 +57,7 @@ private static void useDnsClientProvider() { err.addSuppressed(e); throw err; } - // an exception is expected provided that the assertion succeeds + // an exception is expected because `a.b.c` does not resolve to an IP address } } From 18a1496a0189a94f7c89ed1bac692843d5d2baa0 Mon Sep 17 00:00:00 2001 From: Valentin Kovalenko Date: Fri, 5 Apr 2024 16:22:48 -0600 Subject: [PATCH 07/16] Do minor improvements - Improve logging - Use `clean` instead of `:graalvm-native-image-app:clean` in `readme.md` JAVA-5219 --- graalvm-native-image-app/readme.md | 12 ++++++------ .../main/com/mongodb/internal/graalvm/DnsSpi.java | 6 ++++-- .../com/mongodb/internal/graalvm/NativeImageApp.java | 2 +- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/graalvm-native-image-app/readme.md b/graalvm-native-image-app/readme.md index bb974fdd063..a659b7d1c07 100644 --- a/graalvm-native-image-app/readme.md +++ b/graalvm-native-image-app/readme.md @@ -47,12 +47,12 @@ you need to inform Gradle about that location as specified in https://docs.gradl Assuming that your MongoDB deployment is accessible at `mongodb://localhost:27017`, run from the driver project root directory: -| # | Command | Description | -|--------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------| -| 0 | `env JAVA_HOME="${JDK17}" ./gradlew -PjavaVersion=21 :graalvm-native-image-app:nativeCompile` | Build the application relying on the reachability metadata stored in `graalvm-native-image-app/src/main/resources/META-INF/native-image`. | -| 1 | `env JAVA_HOME="${JDK17}" ./gradlew :graalvm-native-image-app:clean && env JAVA_HOME=${JDK21_GRAALVM} ./gradlew -PjavaVersion=21 -Pagent :graalvm-native-image-app:run && env JAVA_HOME=${JDK21_GRAALVM} ./gradlew :graalvm-native-image-app:metadataCopy` | Collect the reachability metadata and update the files storing it. Do this before building the application only if building fails otherwise. | -| 2 | `./graalvm-native-image-app/build/native/nativeCompile/NativeImageApp` | Run the application that has been built. | -| 3 | `env JAVA_HOME="${JDK17}" ./gradlew -PjavaVersion=21 :graalvm-native-image-app:nativeRun` | Run the application using Gradle, build it if necessary relying on the stored reachability metadata. | +| # | Command | Description | +|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------| +| 0 | `env JAVA_HOME="${JDK17}" ./gradlew -PjavaVersion=21 :graalvm-native-image-app:nativeCompile` | Build the application relying on the reachability metadata stored in `graalvm-native-image-app/src/main/resources/META-INF/native-image`. | +| 1 | `env JAVA_HOME="${JDK17}" ./gradlew clean && env JAVA_HOME=${JDK21_GRAALVM} ./gradlew -PjavaVersion=21 -Pagent :graalvm-native-image-app:run && env JAVA_HOME=${JDK21_GRAALVM} ./gradlew :graalvm-native-image-app:metadataCopy` | Collect the reachability metadata and update the files storing it. Do this before building the application only if building fails otherwise. | +| 2 | `./graalvm-native-image-app/build/native/nativeCompile/NativeImageApp` | Run the application that has been built. | +| 3 | `env JAVA_HOME="${JDK17}" ./gradlew -PjavaVersion=21 :graalvm-native-image-app:nativeRun` | Run the application using Gradle, build it if necessary relying on the stored reachability metadata. | #### Specifying a custom connection string diff --git a/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/DnsSpi.java b/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/DnsSpi.java index f3a78d4cabe..e1d6ad72bfd 100644 --- a/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/DnsSpi.java +++ b/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/DnsSpi.java @@ -34,7 +34,8 @@ public static void main(final String... args) { private static void useInetAddressResolverProvider(final String... args) { try (MongoClient client = args.length == 0 ? MongoClients.create() : MongoClients.create(args[0])) { - LOGGER.info("Database names: {}", client.listDatabaseNames().into(new ArrayList<>())); + ArrayList databaseNames = client.listDatabaseNames().into(new ArrayList<>()); + LOGGER.info("Database names: {}", databaseNames); } CustomInetAddressResolverProvider.assertUsed(); } @@ -49,7 +50,8 @@ private static void useDnsClientProvider() { // This is a tolerable race condition for a test. .serverSelectionTimeout(2, TimeUnit.SECONDS)) .build())) { - LOGGER.info("Database names: {}", client.listDatabaseNames().into(new ArrayList<>())); + ArrayList databaseNames = client.listDatabaseNames().into(new ArrayList<>()); + LOGGER.info("Database names: {}", databaseNames); } catch (RuntimeException e) { try { CustomDnsClientProvider.assertUsed(); diff --git a/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/NativeImageApp.java b/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/NativeImageApp.java index 5803fccf398..83478cf3059 100644 --- a/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/NativeImageApp.java +++ b/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/NativeImageApp.java @@ -121,7 +121,7 @@ final class Named implements ThrowingRunnable { try { runnable.run(); } catch (Exception | AssertionError e) { - LOGGER.debug("Failure in {}", name, e); + LOGGER.info("Failure in {}", name, e); throw e; } finally { LOGGER.info("End {}", name); From 261841a69dd82774022b13ada2b8e84bb65f80ab Mon Sep 17 00:00:00 2001 From: Valentin Kovalenko Date: Fri, 5 Apr 2024 16:51:52 -0600 Subject: [PATCH 08/16] Remove Snappy-related GraalVM substitutions Given that the snappy compressor works in GraalVM, we don't need any substitutions for it. JAVA-5219 --- config/spotbugs/exclude.xml | 4 --- .../src/main/com/mongodb/MongoCompressor.java | 2 -- .../MongoCompressorSubstitution.java | 31 ------------------- 3 files changed, 37 deletions(-) delete mode 100644 driver-core/src/main/com/mongodb/internal/graalvm/substitution/MongoCompressorSubstitution.java diff --git a/config/spotbugs/exclude.xml b/config/spotbugs/exclude.xml index 28f50a725eb..d35f0a81c8a 100644 --- a/config/spotbugs/exclude.xml +++ b/config/spotbugs/exclude.xml @@ -276,9 +276,5 @@ - - - - diff --git a/driver-core/src/main/com/mongodb/MongoCompressor.java b/driver-core/src/main/com/mongodb/MongoCompressor.java index 4c9d866979a..57f88716d89 100644 --- a/driver-core/src/main/com/mongodb/MongoCompressor.java +++ b/driver-core/src/main/com/mongodb/MongoCompressor.java @@ -16,7 +16,6 @@ package com.mongodb; -import com.mongodb.internal.graalvm.substitution.MongoCompressorSubstitution; import com.mongodb.lang.Nullable; import java.util.Collections; @@ -47,7 +46,6 @@ public final class MongoCompressor { * * @return A compressor based on the snappy compression algorithm * @mongodb.server.release 3.4 - * @throws UnsupportedOperationException If {@linkplain MongoCompressorSubstitution#createSnappyCompressor() called in a GraalVM native image}. */ public static MongoCompressor createSnappyCompressor() { return new MongoCompressor("snappy"); diff --git a/driver-core/src/main/com/mongodb/internal/graalvm/substitution/MongoCompressorSubstitution.java b/driver-core/src/main/com/mongodb/internal/graalvm/substitution/MongoCompressorSubstitution.java deleted file mode 100644 index 36694ab8ef8..00000000000 --- a/driver-core/src/main/com/mongodb/internal/graalvm/substitution/MongoCompressorSubstitution.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2008-present MongoDB, Inc. - * - * 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 - * - * http://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.mongodb.internal.graalvm.substitution; - -import com.mongodb.MongoCompressor; -import com.oracle.svm.core.annotate.Substitute; -import com.oracle.svm.core.annotate.TargetClass; - -@TargetClass(MongoCompressor.class) -public final class MongoCompressorSubstitution { - @Substitute - public static MongoCompressor createSnappyCompressor() { - throw new UnsupportedOperationException("Snappy compressor is not supported in GraalVM native image"); - } - - private MongoCompressorSubstitution() { - } -} From fe51f0e9622daf6b50a5a5a318316310343088b4 Mon Sep 17 00:00:00 2001 From: Valentin Kovalenko Date: Fri, 5 Apr 2024 17:36:08 -0600 Subject: [PATCH 09/16] Move shared library resource entries to :graalvm-native-image-app Having these entries results in a larger native image, even if the shared libraries are not used by the application. Therefore, we won't supply the entries with our JARs, but will document this for users and propose the `resource-config.json` in :graalvm-native-image-app as an example where users may pick the necessary entries from if need be. JAVA-5219 --- .../native-image/resource-config.json | 26 ------------------- .../native-image/resource-config.json | 26 +++++++++++++++++++ 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/driver-core/src/main/resources/META-INF/native-image/resource-config.json b/driver-core/src/main/resources/META-INF/native-image/resource-config.json index 84fac027a25..43d3d5bb969 100644 --- a/driver-core/src/main/resources/META-INF/native-image/resource-config.json +++ b/driver-core/src/main/resources/META-INF/native-image/resource-config.json @@ -4,32 +4,6 @@ "pattern":"\\QMETA-INF/services/com.mongodb.spi.dns.DnsClientProvider\\E" }, { "pattern":"\\QMETA-INF/services/com.mongodb.spi.dns.InetAddressResolverProvider\\E" - }, { - "pattern":"\\Qcom/sun/jna/darwin-aarch64/libjnidispatch.jnilib\\E" - }, { - "pattern":"\\Qcom/sun/jna/darwin-x86-64/libjnidispatch.jnilib\\E" - }, { - "pattern":"\\Qcom/sun/jna/linux-aarch64/libjnidispatch.so\\E" - }, { - "pattern":"\\Qcom/sun/jna/linux-ppc64le/libjnidispatch.so\\E" - }, { - "pattern":"\\Qcom/sun/jna/linux-s390x/libjnidispatch.so\\E" - }, { - "pattern":"\\Qcom/sun/jna/linux-x86-64/libjnidispatch.so\\E" - }, { - "pattern":"\\Qcom/sun/jna/win32-x86-64/jnidispatch.dll\\E" - }, { - "pattern":"\\Qdarwin/libmongocrypt.dylib\\E" - }, { - "pattern":"\\Qlinux-aarch64/libmongocrypt.so\\E" - }, { - "pattern":"\\Qlinux-ppc64le/libmongocrypt.so\\E" - }, { - "pattern":"\\Qlinux-s390x/libmongocrypt.so\\E" - }, { - "pattern":"\\Qlinux-x86-64/libmongocrypt.so\\E" - }, { - "pattern":"\\Qwin32-x86-64/mongocrypt.dll\\E" }]}, "bundles":[] } diff --git a/graalvm-native-image-app/src/main/resources/META-INF/native-image/resource-config.json b/graalvm-native-image-app/src/main/resources/META-INF/native-image/resource-config.json index 3099bc884c0..d4bf7ea12ff 100644 --- a/graalvm-native-image-app/src/main/resources/META-INF/native-image/resource-config.json +++ b/graalvm-native-image-app/src/main/resources/META-INF/native-image/resource-config.json @@ -1,6 +1,32 @@ { "resources":{ "includes":[{ + "pattern":"\\Qcom/sun/jna/darwin-aarch64/libjnidispatch.jnilib\\E" + }, { + "pattern":"\\Qcom/sun/jna/darwin-x86-64/libjnidispatch.jnilib\\E" + }, { + "pattern":"\\Qcom/sun/jna/linux-aarch64/libjnidispatch.so\\E" + }, { + "pattern":"\\Qcom/sun/jna/linux-ppc64le/libjnidispatch.so\\E" + }, { + "pattern":"\\Qcom/sun/jna/linux-s390x/libjnidispatch.so\\E" + }, { + "pattern":"\\Qcom/sun/jna/linux-x86-64/libjnidispatch.so\\E" + }, { + "pattern":"\\Qcom/sun/jna/win32-x86-64/jnidispatch.dll\\E" + }, { + "pattern":"\\Qdarwin/libmongocrypt.dylib\\E" + }, { + "pattern":"\\Qlinux-aarch64/libmongocrypt.so\\E" + }, { + "pattern":"\\Qlinux-ppc64le/libmongocrypt.so\\E" + }, { + "pattern":"\\Qlinux-s390x/libmongocrypt.so\\E" + }, { + "pattern":"\\Qlinux-x86-64/libmongocrypt.so\\E" + }, { + "pattern":"\\Qwin32-x86-64/mongocrypt.dll\\E" + }, { "pattern":"\\QMETA-INF/services/ch.qos.logback.classic.spi.Configurator\\E" }, { "pattern":"\\QMETA-INF/services/java.lang.System$LoggerFinder\\E" From 7c8b08a68b7709cfb8904fa00518bf09acabc4c2 Mon Sep 17 00:00:00 2001 From: Valentin Kovalenko Date: Mon, 8 Apr 2024 09:07:18 -0600 Subject: [PATCH 10/16] Add JDK-specific reachability metadata to `org.mongodb:mongodb-driver-core` Without this metadata an application using the driver won't work, and there is no other place this metadata may come from, unless it is gathered via the GraalVM tracing agent. It's weird that we have to include reachability metadata specific to JDK, but there is nothing to do about it, other than saying that users are to collect the metadata for their applications themselves. The latter actually seems like the only right way to do this, but it conflicts with the fact that there is Oracle's reachability metadata repository (https://github.com/oracle/graalvm-reachability-metadata). JAVA-5219 --- .../META-INF/native-image/jni-config.json | 158 ++++++++++++++++++ .../META-INF/native-image/reflect-config.json | 152 +++++++++++++++++ .../META-INF/native-image/jni-config.json | 158 ------------------ .../META-INF/native-image/reflect-config.json | 152 ----------------- 4 files changed, 310 insertions(+), 310 deletions(-) diff --git a/driver-core/src/main/resources/META-INF/native-image/jni-config.json b/driver-core/src/main/resources/META-INF/native-image/jni-config.json index ef5ea8e42da..44e398cb556 100644 --- a/driver-core/src/main/resources/META-INF/native-image/jni-config.json +++ b/driver-core/src/main/resources/META-INF/native-image/jni-config.json @@ -18,5 +18,163 @@ { "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_random_fn", "methods":[{"name":"random","parameterTypes":["com.sun.jna.Pointer","com.mongodb.crypt.capi.CAPI$mongocrypt_binary_t","int","com.mongodb.crypt.capi.CAPI$mongocrypt_status_t"] }] +}, +{ + "name":"com.sun.jna.Callback" +}, +{ + "name":"com.sun.jna.CallbackReference", + "methods":[{"name":"getCallback","parameterTypes":["java.lang.Class","com.sun.jna.Pointer","boolean"] }, {"name":"getFunctionPointer","parameterTypes":["com.sun.jna.Callback","boolean"] }, {"name":"getNativeString","parameterTypes":["java.lang.Object","boolean"] }, {"name":"initializeThread","parameterTypes":["com.sun.jna.Callback","com.sun.jna.CallbackReference$AttachOptions"] }] +}, +{ + "name":"com.sun.jna.CallbackReference$AttachOptions" +}, +{ + "name":"com.sun.jna.FromNativeConverter", + "methods":[{"name":"nativeType","parameterTypes":[] }] +}, +{ + "name":"com.sun.jna.IntegerType", + "fields":[{"name":"value"}] +}, +{ + "name":"com.sun.jna.JNIEnv" +}, +{ + "name":"com.sun.jna.Native", + "methods":[{"name":"dispose","parameterTypes":[] }, {"name":"fromNative","parameterTypes":["com.sun.jna.FromNativeConverter","java.lang.Object","java.lang.reflect.Method"] }, {"name":"fromNative","parameterTypes":["java.lang.Class","java.lang.Object"] }, {"name":"fromNative","parameterTypes":["java.lang.reflect.Method","java.lang.Object"] }, {"name":"nativeType","parameterTypes":["java.lang.Class"] }, {"name":"toNative","parameterTypes":["com.sun.jna.ToNativeConverter","java.lang.Object"] }] +}, +{ + "name":"com.sun.jna.Native$ffi_callback", + "methods":[{"name":"invoke","parameterTypes":["long","long","long"] }] +}, +{ + "name":"com.sun.jna.NativeMapped", + "methods":[{"name":"toNative","parameterTypes":[] }] +}, +{ + "name":"com.sun.jna.Pointer", + "fields":[{"name":"peer"}], + "methods":[{"name":"","parameterTypes":["long"] }] +}, +{ + "name":"com.sun.jna.PointerType", + "fields":[{"name":"pointer"}] +}, +{ + "name":"com.sun.jna.Structure", + "fields":[{"name":"memory"}, {"name":"typeInfo"}], + "methods":[{"name":"autoRead","parameterTypes":[] }, {"name":"autoWrite","parameterTypes":[] }, {"name":"getTypeInfo","parameterTypes":[] }, {"name":"newInstance","parameterTypes":["java.lang.Class","long"] }] +}, +{ + "name":"com.sun.jna.Structure$ByValue" +}, +{ + "name":"com.sun.jna.Structure$FFIType$FFITypes", + "fields":[{"name":"ffi_type_double"}, {"name":"ffi_type_float"}, {"name":"ffi_type_longdouble"}, {"name":"ffi_type_pointer"}, {"name":"ffi_type_sint16"}, {"name":"ffi_type_sint32"}, {"name":"ffi_type_sint64"}, {"name":"ffi_type_sint8"}, {"name":"ffi_type_uint16"}, {"name":"ffi_type_uint32"}, {"name":"ffi_type_uint64"}, {"name":"ffi_type_uint8"}, {"name":"ffi_type_void"}] +}, +{ + "name":"com.sun.jna.WString", + "methods":[{"name":"","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"java.lang.Boolean", + "fields":[{"name":"TYPE"}, {"name":"value"}], + "methods":[{"name":"","parameterTypes":["boolean"] }, {"name":"getBoolean","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"java.lang.Byte", + "fields":[{"name":"TYPE"}, {"name":"value"}], + "methods":[{"name":"","parameterTypes":["byte"] }] +}, +{ + "name":"java.lang.Character", + "fields":[{"name":"TYPE"}, {"name":"value"}], + "methods":[{"name":"","parameterTypes":["char"] }] +}, +{ + "name":"java.lang.Class", + "methods":[{"name":"getComponentType","parameterTypes":[] }] +}, +{ + "name":"java.lang.Double", + "fields":[{"name":"TYPE"}, {"name":"value"}], + "methods":[{"name":"","parameterTypes":["double"] }] +}, +{ + "name":"java.lang.Float", + "fields":[{"name":"TYPE"}, {"name":"value"}], + "methods":[{"name":"","parameterTypes":["float"] }] +}, +{ + "name":"java.lang.Integer", + "fields":[{"name":"TYPE"}, {"name":"value"}], + "methods":[{"name":"","parameterTypes":["int"] }] +}, +{ + "name":"java.lang.Long", + "fields":[{"name":"TYPE"}, {"name":"value"}], + "methods":[{"name":"","parameterTypes":["long"] }] +}, +{ + "name":"java.lang.Object", + "methods":[{"name":"toString","parameterTypes":[] }] +}, +{ + "name":"java.lang.Short", + "fields":[{"name":"TYPE"}, {"name":"value"}], + "methods":[{"name":"","parameterTypes":["short"] }] +}, +{ + "name":"java.lang.String", + "methods":[{"name":"","parameterTypes":["byte[]"] }, {"name":"","parameterTypes":["byte[]","java.lang.String"] }, {"name":"getBytes","parameterTypes":[] }, {"name":"getBytes","parameterTypes":["java.lang.String"] }, {"name":"lastIndexOf","parameterTypes":["int"] }, {"name":"substring","parameterTypes":["int"] }, {"name":"toCharArray","parameterTypes":[] }] +}, +{ + "name":"java.lang.System", + "methods":[{"name":"getProperty","parameterTypes":["java.lang.String"] }, {"name":"setProperty","parameterTypes":["java.lang.String","java.lang.String"] }] +}, +{ + "name":"java.lang.UnsatisfiedLinkError", + "methods":[{"name":"","parameterTypes":["java.lang.String"] }] +}, +{ + "name":"java.lang.Void", + "fields":[{"name":"TYPE"}] +}, +{ + "name":"java.lang.reflect.Method", + "methods":[{"name":"getParameterTypes","parameterTypes":[] }, {"name":"getReturnType","parameterTypes":[] }] +}, +{ + "name":"java.nio.Buffer", + "methods":[{"name":"position","parameterTypes":[] }] +}, +{ + "name":"java.nio.ByteBuffer", + "methods":[{"name":"array","parameterTypes":[] }, {"name":"arrayOffset","parameterTypes":[] }] +}, +{ + "name":"java.nio.CharBuffer", + "methods":[{"name":"array","parameterTypes":[] }, {"name":"arrayOffset","parameterTypes":[] }] +}, +{ + "name":"java.nio.DoubleBuffer", + "methods":[{"name":"array","parameterTypes":[] }, {"name":"arrayOffset","parameterTypes":[] }] +}, +{ + "name":"java.nio.FloatBuffer", + "methods":[{"name":"array","parameterTypes":[] }, {"name":"arrayOffset","parameterTypes":[] }] +}, +{ + "name":"java.nio.IntBuffer", + "methods":[{"name":"array","parameterTypes":[] }, {"name":"arrayOffset","parameterTypes":[] }] +}, +{ + "name":"java.nio.LongBuffer", + "methods":[{"name":"array","parameterTypes":[] }, {"name":"arrayOffset","parameterTypes":[] }] +}, +{ + "name":"java.nio.ShortBuffer", + "methods":[{"name":"array","parameterTypes":[] }, {"name":"arrayOffset","parameterTypes":[] }] } ] diff --git a/driver-core/src/main/resources/META-INF/native-image/reflect-config.json b/driver-core/src/main/resources/META-INF/native-image/reflect-config.json index c326eb751bf..cd7ec099635 100644 --- a/driver-core/src/main/resources/META-INF/native-image/reflect-config.json +++ b/driver-core/src/main/resources/META-INF/native-image/reflect-config.json @@ -92,5 +92,157 @@ { "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_t", "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"boolean", + "fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}] +}, +{ + "name":"com.sun.crypto.provider.AESCipher$General", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.sun.crypto.provider.HmacCore$HmacSHA256", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.sun.crypto.provider.HmacCore$HmacSHA512", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.sun.jna.CallbackProxy", + "methods":[{"name":"callback","parameterTypes":["java.lang.Object[]"] }] +}, +{ + "name":"com.sun.jna.Pointer", + "fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}] +}, +{ + "name":"com.sun.jna.Structure$FFIType", + "allDeclaredFields":true, + "queryAllPublicConstructors":true, + "fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}], + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.sun.jna.Structure$FFIType$size_t", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.sun.jna.ptr.PointerByReference", + "fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}], + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"int", + "fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}] +}, +{ + "name":"java.io.FilePermission" +}, +{ + "name":"java.lang.Object", + "queryAllDeclaredMethods":true +}, +{ + "name":"java.lang.Record" +}, +{ + "name":"java.lang.RuntimePermission" +}, +{ + "name":"java.lang.Thread", + "fields":[{"name":"threadLocalRandomProbe"}] +}, +{ + "name":"java.lang.Throwable", + "methods":[{"name":"addSuppressed","parameterTypes":["java.lang.Throwable"] }] +}, +{ + "name":"java.lang.reflect.Method", + "methods":[{"name":"isVarArgs","parameterTypes":[] }] +}, +{ + "name":"java.net.NetPermission" +}, +{ + "name":"java.net.Socket", + "methods":[{"name":"setOption","parameterTypes":["java.net.SocketOption","java.lang.Object"] }] +}, +{ + "name":"java.net.SocketPermission" +}, +{ + "name":"java.net.URLPermission", + "methods":[{"name":"","parameterTypes":["java.lang.String","java.lang.String"] }] +}, +{ + "name":"java.nio.Buffer" +}, +{ + "name":"java.security.AllPermission" +}, +{ + "name":"java.security.SecureRandomParameters" +}, +{ + "name":"java.security.SecurityPermission" +}, +{ + "name":"java.util.PropertyPermission" +}, +{ + "name":"java.util.concurrent.ForkJoinTask", + "fields":[{"name":"aux"}, {"name":"status"}] +}, +{ + "name":"java.util.concurrent.atomic.AtomicBoolean", + "fields":[{"name":"value"}] +}, +{ + "name":"java.util.concurrent.atomic.AtomicReference", + "fields":[{"name":"value"}] +}, +{ + "name":"java.util.concurrent.atomic.Striped64", + "fields":[{"name":"base"}, {"name":"cellsBusy"}] +}, +{ + "name":"javax.smartcardio.CardPermission" +}, +{ + "name":"jdk.internal.misc.Unsafe" +}, +{ + "name":"jdk.net.ExtendedSocketOptions", + "fields":[{"name":"TCP_KEEPCOUNT"}, {"name":"TCP_KEEPIDLE"}, {"name":"TCP_KEEPINTERVAL"}] +}, +{ + "name":"long", + "fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}] +}, +{ + "name":"sun.security.provider.NativePRNG", + "methods":[{"name":"","parameterTypes":[] }, {"name":"","parameterTypes":["java.security.SecureRandomParameters"] }] +}, +{ + "name":"sun.security.provider.SHA", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.provider.SHA2$SHA256", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"sun.security.provider.SHA5$SHA512", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"void", + "fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}] } ] diff --git a/graalvm-native-image-app/src/main/resources/META-INF/native-image/jni-config.json b/graalvm-native-image-app/src/main/resources/META-INF/native-image/jni-config.json index 1d3533f349b..2be5d0ca308 100644 --- a/graalvm-native-image-app/src/main/resources/META-INF/native-image/jni-config.json +++ b/graalvm-native-image-app/src/main/resources/META-INF/native-image/jni-config.json @@ -2,163 +2,5 @@ { "name":"com.mongodb.internal.graalvm.NativeImageApp", "methods":[{"name":"main","parameterTypes":["java.lang.String[]"] }] -}, -{ - "name":"com.sun.jna.Callback" -}, -{ - "name":"com.sun.jna.CallbackReference", - "methods":[{"name":"getCallback","parameterTypes":["java.lang.Class","com.sun.jna.Pointer","boolean"] }, {"name":"getFunctionPointer","parameterTypes":["com.sun.jna.Callback","boolean"] }, {"name":"getNativeString","parameterTypes":["java.lang.Object","boolean"] }, {"name":"initializeThread","parameterTypes":["com.sun.jna.Callback","com.sun.jna.CallbackReference$AttachOptions"] }] -}, -{ - "name":"com.sun.jna.CallbackReference$AttachOptions" -}, -{ - "name":"com.sun.jna.FromNativeConverter", - "methods":[{"name":"nativeType","parameterTypes":[] }] -}, -{ - "name":"com.sun.jna.IntegerType", - "fields":[{"name":"value"}] -}, -{ - "name":"com.sun.jna.JNIEnv" -}, -{ - "name":"com.sun.jna.Native", - "methods":[{"name":"dispose","parameterTypes":[] }, {"name":"fromNative","parameterTypes":["com.sun.jna.FromNativeConverter","java.lang.Object","java.lang.reflect.Method"] }, {"name":"fromNative","parameterTypes":["java.lang.Class","java.lang.Object"] }, {"name":"fromNative","parameterTypes":["java.lang.reflect.Method","java.lang.Object"] }, {"name":"nativeType","parameterTypes":["java.lang.Class"] }, {"name":"toNative","parameterTypes":["com.sun.jna.ToNativeConverter","java.lang.Object"] }] -}, -{ - "name":"com.sun.jna.Native$ffi_callback", - "methods":[{"name":"invoke","parameterTypes":["long","long","long"] }] -}, -{ - "name":"com.sun.jna.NativeMapped", - "methods":[{"name":"toNative","parameterTypes":[] }] -}, -{ - "name":"com.sun.jna.Pointer", - "fields":[{"name":"peer"}], - "methods":[{"name":"","parameterTypes":["long"] }] -}, -{ - "name":"com.sun.jna.PointerType", - "fields":[{"name":"pointer"}] -}, -{ - "name":"com.sun.jna.Structure", - "fields":[{"name":"memory"}, {"name":"typeInfo"}], - "methods":[{"name":"autoRead","parameterTypes":[] }, {"name":"autoWrite","parameterTypes":[] }, {"name":"getTypeInfo","parameterTypes":[] }, {"name":"newInstance","parameterTypes":["java.lang.Class","long"] }] -}, -{ - "name":"com.sun.jna.Structure$ByValue" -}, -{ - "name":"com.sun.jna.Structure$FFIType$FFITypes", - "fields":[{"name":"ffi_type_double"}, {"name":"ffi_type_float"}, {"name":"ffi_type_longdouble"}, {"name":"ffi_type_pointer"}, {"name":"ffi_type_sint16"}, {"name":"ffi_type_sint32"}, {"name":"ffi_type_sint64"}, {"name":"ffi_type_sint8"}, {"name":"ffi_type_uint16"}, {"name":"ffi_type_uint32"}, {"name":"ffi_type_uint64"}, {"name":"ffi_type_uint8"}, {"name":"ffi_type_void"}] -}, -{ - "name":"com.sun.jna.WString", - "methods":[{"name":"","parameterTypes":["java.lang.String"] }] -}, -{ - "name":"java.lang.Boolean", - "fields":[{"name":"TYPE"}, {"name":"value"}], - "methods":[{"name":"","parameterTypes":["boolean"] }, {"name":"getBoolean","parameterTypes":["java.lang.String"] }] -}, -{ - "name":"java.lang.Byte", - "fields":[{"name":"TYPE"}, {"name":"value"}], - "methods":[{"name":"","parameterTypes":["byte"] }] -}, -{ - "name":"java.lang.Character", - "fields":[{"name":"TYPE"}, {"name":"value"}], - "methods":[{"name":"","parameterTypes":["char"] }] -}, -{ - "name":"java.lang.Class", - "methods":[{"name":"getComponentType","parameterTypes":[] }] -}, -{ - "name":"java.lang.Double", - "fields":[{"name":"TYPE"}, {"name":"value"}], - "methods":[{"name":"","parameterTypes":["double"] }] -}, -{ - "name":"java.lang.Float", - "fields":[{"name":"TYPE"}, {"name":"value"}], - "methods":[{"name":"","parameterTypes":["float"] }] -}, -{ - "name":"java.lang.Integer", - "fields":[{"name":"TYPE"}, {"name":"value"}], - "methods":[{"name":"","parameterTypes":["int"] }] -}, -{ - "name":"java.lang.Long", - "fields":[{"name":"TYPE"}, {"name":"value"}], - "methods":[{"name":"","parameterTypes":["long"] }] -}, -{ - "name":"java.lang.Object", - "methods":[{"name":"toString","parameterTypes":[] }] -}, -{ - "name":"java.lang.Short", - "fields":[{"name":"TYPE"}, {"name":"value"}], - "methods":[{"name":"","parameterTypes":["short"] }] -}, -{ - "name":"java.lang.String", - "methods":[{"name":"","parameterTypes":["byte[]"] }, {"name":"","parameterTypes":["byte[]","java.lang.String"] }, {"name":"getBytes","parameterTypes":[] }, {"name":"getBytes","parameterTypes":["java.lang.String"] }, {"name":"lastIndexOf","parameterTypes":["int"] }, {"name":"substring","parameterTypes":["int"] }, {"name":"toCharArray","parameterTypes":[] }] -}, -{ - "name":"java.lang.System", - "methods":[{"name":"getProperty","parameterTypes":["java.lang.String"] }, {"name":"setProperty","parameterTypes":["java.lang.String","java.lang.String"] }] -}, -{ - "name":"java.lang.UnsatisfiedLinkError", - "methods":[{"name":"","parameterTypes":["java.lang.String"] }] -}, -{ - "name":"java.lang.Void", - "fields":[{"name":"TYPE"}] -}, -{ - "name":"java.lang.reflect.Method", - "methods":[{"name":"getParameterTypes","parameterTypes":[] }, {"name":"getReturnType","parameterTypes":[] }] -}, -{ - "name":"java.nio.Buffer", - "methods":[{"name":"position","parameterTypes":[] }] -}, -{ - "name":"java.nio.ByteBuffer", - "methods":[{"name":"array","parameterTypes":[] }, {"name":"arrayOffset","parameterTypes":[] }] -}, -{ - "name":"java.nio.CharBuffer", - "methods":[{"name":"array","parameterTypes":[] }, {"name":"arrayOffset","parameterTypes":[] }] -}, -{ - "name":"java.nio.DoubleBuffer", - "methods":[{"name":"array","parameterTypes":[] }, {"name":"arrayOffset","parameterTypes":[] }] -}, -{ - "name":"java.nio.FloatBuffer", - "methods":[{"name":"array","parameterTypes":[] }, {"name":"arrayOffset","parameterTypes":[] }] -}, -{ - "name":"java.nio.IntBuffer", - "methods":[{"name":"array","parameterTypes":[] }, {"name":"arrayOffset","parameterTypes":[] }] -}, -{ - "name":"java.nio.LongBuffer", - "methods":[{"name":"array","parameterTypes":[] }, {"name":"arrayOffset","parameterTypes":[] }] -}, -{ - "name":"java.nio.ShortBuffer", - "methods":[{"name":"array","parameterTypes":[] }, {"name":"arrayOffset","parameterTypes":[] }] } ] diff --git a/graalvm-native-image-app/src/main/resources/META-INF/native-image/reflect-config.json b/graalvm-native-image-app/src/main/resources/META-INF/native-image/reflect-config.json index 4b32b61c781..b99f29159a7 100644 --- a/graalvm-native-image-app/src/main/resources/META-INF/native-image/reflect-config.json +++ b/graalvm-native-image-app/src/main/resources/META-INF/native-image/reflect-config.json @@ -1,8 +1,4 @@ [ -{ - "name":"boolean", - "fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}] -}, { "name":"ch.qos.logback.classic.encoder.PatternLayoutEncoder", "queryAllPublicMethods":true, @@ -65,134 +61,6 @@ "name":"ch.qos.logback.core.spi.ContextAware", "methods":[{"name":"valueOf","parameterTypes":["java.lang.String"] }] }, -{ - "name":"com.sun.crypto.provider.AESCipher$General", - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"com.sun.crypto.provider.HmacCore$HmacSHA256", - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"com.sun.crypto.provider.HmacCore$HmacSHA512", - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"com.sun.jna.CallbackProxy", - "methods":[{"name":"callback","parameterTypes":["java.lang.Object[]"] }] -}, -{ - "name":"com.sun.jna.Pointer", - "fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}] -}, -{ - "name":"com.sun.jna.Structure$FFIType", - "allDeclaredFields":true, - "queryAllPublicConstructors":true, - "fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}], - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"com.sun.jna.Structure$FFIType$size_t", - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"com.sun.jna.ptr.PointerByReference", - "fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}], - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl", - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"int", - "fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}] -}, -{ - "name":"java.io.FilePermission" -}, -{ - "name":"java.lang.Object", - "queryAllDeclaredMethods":true -}, -{ - "name":"java.lang.Record" -}, -{ - "name":"java.lang.RuntimePermission" -}, -{ - "name":"java.lang.Thread", - "fields":[{"name":"threadLocalRandomProbe"}] -}, -{ - "name":"java.lang.Throwable", - "methods":[{"name":"addSuppressed","parameterTypes":["java.lang.Throwable"] }] -}, -{ - "name":"java.lang.reflect.Method", - "methods":[{"name":"isVarArgs","parameterTypes":[] }] -}, -{ - "name":"java.net.NetPermission" -}, -{ - "name":"java.net.Socket", - "methods":[{"name":"setOption","parameterTypes":["java.net.SocketOption","java.lang.Object"] }] -}, -{ - "name":"java.net.SocketPermission" -}, -{ - "name":"java.net.URLPermission", - "methods":[{"name":"","parameterTypes":["java.lang.String","java.lang.String"] }] -}, -{ - "name":"java.nio.Buffer" -}, -{ - "name":"java.security.AllPermission" -}, -{ - "name":"java.security.SecureRandomParameters" -}, -{ - "name":"java.security.SecurityPermission" -}, -{ - "name":"java.util.PropertyPermission" -}, -{ - "name":"java.util.concurrent.ForkJoinTask", - "fields":[{"name":"aux"}, {"name":"status"}] -}, -{ - "name":"java.util.concurrent.atomic.AtomicBoolean", - "fields":[{"name":"value"}] -}, -{ - "name":"java.util.concurrent.atomic.AtomicReference", - "fields":[{"name":"value"}] -}, -{ - "name":"java.util.concurrent.atomic.Striped64", - "fields":[{"name":"base"}, {"name":"cellsBusy"}] -}, -{ - "name":"javax.smartcardio.CardPermission" -}, -{ - "name":"jdk.internal.misc.Unsafe" -}, -{ - "name":"jdk.net.ExtendedSocketOptions", - "fields":[{"name":"TCP_KEEPCOUNT"}, {"name":"TCP_KEEPIDLE"}, {"name":"TCP_KEEPINTERVAL"}] -}, -{ - "name":"long", - "fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}] -}, { "name":"org.slf4j.Logger" }, @@ -306,22 +174,6 @@ "name":"reactor.util.concurrent.SpscLinkedArrayQueue", "fields":[{"name":"consumerIndex"}, {"name":"producerIndex"}] }, -{ - "name":"sun.security.provider.NativePRNG", - "methods":[{"name":"","parameterTypes":[] }, {"name":"","parameterTypes":["java.security.SecureRandomParameters"] }] -}, -{ - "name":"sun.security.provider.SHA", - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"sun.security.provider.SHA2$SHA256", - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"sun.security.provider.SHA5$SHA512", - "methods":[{"name":"","parameterTypes":[] }] -}, { "name":"tour.Address", "allDeclaredFields":true, @@ -335,9 +187,5 @@ "queryAllDeclaredMethods":true, "queryAllDeclaredConstructors":true, "methods":[{"name":"","parameterTypes":[] }, {"name":"getAddress","parameterTypes":[] }, {"name":"getAge","parameterTypes":[] }, {"name":"getId","parameterTypes":[] }, {"name":"getName","parameterTypes":[] }, {"name":"setAddress","parameterTypes":["tour.Address"] }, {"name":"setAge","parameterTypes":["int"] }, {"name":"setId","parameterTypes":["org.bson.types.ObjectId"] }, {"name":"setName","parameterTypes":["java.lang.String"] }] -}, -{ - "name":"void", - "fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}] } ] From 39291433f659fd46f0617b3afa29d8308a729e47 Mon Sep 17 00:00:00 2001 From: Valentin Kovalenko Date: Mon, 8 Apr 2024 12:05:08 -0600 Subject: [PATCH 11/16] Refactor `UnixServerAddress` substitutions Throwing from the constructor of `UnixServerAddress` seems better than from `SocketStreamFactory.create`. Not only this is more natural, but it also prevents the creation of a `MongoClient`, which wasn't he case previously. JAVA-5219 --- driver-core/build.gradle | 1 - .../main/com/mongodb/UnixServerAddress.java | 12 ++++- .../connection/SocketStreamFactory.java | 11 ----- .../SocketStreamFactorySubstitution.java | 45 ------------------- .../graalvm/substitution/Substitutions.java | 37 --------------- ...ava => UnixServerAddressSubstitution.java} | 10 +++-- .../internal/graalvm/NativeImageApp.java | 5 +-- .../internal/graalvm/Substitutions.java | 45 +++++++++++++++++++ 8 files changed, 63 insertions(+), 103 deletions(-) delete mode 100644 driver-core/src/main/com/mongodb/internal/graalvm/substitution/SocketStreamFactorySubstitution.java delete mode 100644 driver-core/src/main/com/mongodb/internal/graalvm/substitution/Substitutions.java rename driver-core/src/main/com/mongodb/internal/graalvm/substitution/{SubstitutionsSubstitution.java => UnixServerAddressSubstitution.java} (69%) create mode 100644 graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/Substitutions.java diff --git a/driver-core/build.gradle b/driver-core/build.gradle index 2edf69d7133..69a996dc86a 100644 --- a/driver-core/build.gradle +++ b/driver-core/build.gradle @@ -45,7 +45,6 @@ dependencies { api "io.netty:netty-buffer", optional api "io.netty:netty-transport", optional api "io.netty:netty-handler", optional - compileOnly "org.graalvm.sdk:nativeimage:$graalSdkVersion" compileOnly "org.graalvm.sdk:graal-sdk:$graalSdkVersion" // Optionally depend on both AWS SDK v2 and v1. The driver will use v2 is present, v1 if present, or built-in functionality if diff --git a/driver-core/src/main/com/mongodb/UnixServerAddress.java b/driver-core/src/main/com/mongodb/UnixServerAddress.java index c34ccdb74f1..8bd42052004 100644 --- a/driver-core/src/main/com/mongodb/UnixServerAddress.java +++ b/driver-core/src/main/com/mongodb/UnixServerAddress.java @@ -17,14 +17,14 @@ package com.mongodb; import com.mongodb.annotations.Immutable; -import com.mongodb.internal.graalvm.substitution.SocketStreamFactorySubstitution; +import com.mongodb.internal.graalvm.substitution.UnixServerAddressSubstitution; import static com.mongodb.assertions.Assertions.isTrueArgument; import static com.mongodb.assertions.Assertions.notNull; /** * Represents the location of a MongoD unix domain socket. - * It is {@linkplain SocketStreamFactorySubstitution#create(ServerAddress) not supported in GraalVM native image}. + * It is {@linkplain UnixServerAddressSubstitution not supported in GraalVM native image}. * *

Requires the 'jnr.unixsocket' library.

* @since 3.7 @@ -36,10 +36,18 @@ public final class UnixServerAddress extends ServerAddress { /** * Creates a new instance * @param path the path of the MongoD unix domain socket. + * @throws UnsupportedOperationException If {@linkplain UnixServerAddressSubstitution called in a GraalVM native image}. */ public UnixServerAddress(final String path) { super(notNull("The path cannot be null", path)); isTrueArgument("The path must end in .sock", path.endsWith(".sock")); + checkNotInGraalVmNativeImage(); + } + + /** + * @throws UnsupportedOperationException If {@linkplain UnixServerAddressSubstitution called in a GraalVM native image}. + */ + private static void checkNotInGraalVmNativeImage() { } @Override diff --git a/driver-core/src/main/com/mongodb/internal/connection/SocketStreamFactory.java b/driver-core/src/main/com/mongodb/internal/connection/SocketStreamFactory.java index 2b50f29332a..793fc8b3dc4 100644 --- a/driver-core/src/main/com/mongodb/internal/connection/SocketStreamFactory.java +++ b/driver-core/src/main/com/mongodb/internal/connection/SocketStreamFactory.java @@ -21,7 +21,6 @@ import com.mongodb.UnixServerAddress; import com.mongodb.connection.SocketSettings; import com.mongodb.connection.SslSettings; -import com.mongodb.internal.graalvm.substitution.SocketStreamFactorySubstitution; import com.mongodb.spi.dns.InetAddressResolver; import javax.net.SocketFactory; @@ -54,18 +53,8 @@ public SocketStreamFactory(final InetAddressResolver inetAddressResolver, final this.sslSettings = notNull("sslSettings", sslSettings); } - /** - * @see SocketStreamFactorySubstitution#create(ServerAddress) - */ @Override public Stream create(final ServerAddress serverAddress) { - return createInternal(serverAddress); - } - - /** - * @see SocketStreamFactorySubstitution#create(ServerAddress) - */ - private Stream createInternal(final ServerAddress serverAddress) { Stream stream; if (serverAddress instanceof UnixServerAddress) { if (sslSettings.isEnabled()) { diff --git a/driver-core/src/main/com/mongodb/internal/graalvm/substitution/SocketStreamFactorySubstitution.java b/driver-core/src/main/com/mongodb/internal/graalvm/substitution/SocketStreamFactorySubstitution.java deleted file mode 100644 index 581bedff490..00000000000 --- a/driver-core/src/main/com/mongodb/internal/graalvm/substitution/SocketStreamFactorySubstitution.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2008-present MongoDB, Inc. - * - * 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 - * - * http://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.mongodb.internal.graalvm.substitution; - -import com.mongodb.ServerAddress; -import com.mongodb.UnixServerAddress; -import com.mongodb.internal.connection.SocketStreamFactory; -import com.mongodb.internal.connection.Stream; -import com.oracle.svm.core.annotate.Alias; -import com.oracle.svm.core.annotate.Substitute; -import com.oracle.svm.core.annotate.TargetClass; - -import static com.mongodb.assertions.Assertions.fail; - -@TargetClass(SocketStreamFactory.class) -public final class SocketStreamFactorySubstitution { - @Substitute - public Stream create(final ServerAddress serverAddress) { - if (serverAddress instanceof UnixServerAddress) { - throw new UnsupportedOperationException("UnixServerAddress is not supported in GraalVM native image"); - } - return createInternal(serverAddress); - } - - @Alias - private Stream createInternal(final ServerAddress serverAddress) { - throw fail(); - } - - private SocketStreamFactorySubstitution() { - } -} diff --git a/driver-core/src/main/com/mongodb/internal/graalvm/substitution/Substitutions.java b/driver-core/src/main/com/mongodb/internal/graalvm/substitution/Substitutions.java deleted file mode 100644 index f4cea7f33ad..00000000000 --- a/driver-core/src/main/com/mongodb/internal/graalvm/substitution/Substitutions.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2008-present MongoDB, Inc. - * - * 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 - * - * http://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.mongodb.internal.graalvm.substitution; - -import org.graalvm.nativeimage.ImageInfo; - -import static com.mongodb.assertions.Assertions.fail; - -public final class Substitutions { - /** - * @throws AssertionError If called at native image run time, - * unless the method body is substituted using the GraalVM native image technology. - * If not called at native image run time, then does not throw. - * @see SubstitutionsSubstitution#assertUsed() - */ - public static void assertUsed() throws AssertionError { - if (ImageInfo.inImageRuntimeCode()) { - fail("The body of this method must be substituted when compiling using the GraalVM native image technology"); - } - } - - private Substitutions() { - } -} diff --git a/driver-core/src/main/com/mongodb/internal/graalvm/substitution/SubstitutionsSubstitution.java b/driver-core/src/main/com/mongodb/internal/graalvm/substitution/UnixServerAddressSubstitution.java similarity index 69% rename from driver-core/src/main/com/mongodb/internal/graalvm/substitution/SubstitutionsSubstitution.java rename to driver-core/src/main/com/mongodb/internal/graalvm/substitution/UnixServerAddressSubstitution.java index bd5dae5e863..9d52c730c1b 100644 --- a/driver-core/src/main/com/mongodb/internal/graalvm/substitution/SubstitutionsSubstitution.java +++ b/driver-core/src/main/com/mongodb/internal/graalvm/substitution/UnixServerAddressSubstitution.java @@ -15,15 +15,17 @@ */ package com.mongodb.internal.graalvm.substitution; +import com.mongodb.UnixServerAddress; import com.oracle.svm.core.annotate.Substitute; import com.oracle.svm.core.annotate.TargetClass; -@TargetClass(Substitutions.class) -final class SubstitutionsSubstitution { +@TargetClass(UnixServerAddress.class) +public final class UnixServerAddressSubstitution { @Substitute - public static void assertUsed() { + private static void checkNotInGraalVmNativeImage() { + throw new UnsupportedOperationException("UnixServerAddress is not supported in GraalVM native image"); } - private SubstitutionsSubstitution() { + private UnixServerAddressSubstitution() { } } diff --git a/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/NativeImageApp.java b/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/NativeImageApp.java index 83478cf3059..59778d7686f 100644 --- a/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/NativeImageApp.java +++ b/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/NativeImageApp.java @@ -15,7 +15,6 @@ */ package com.mongodb.internal.graalvm; -import com.mongodb.internal.graalvm.substitution.Substitutions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -36,8 +35,8 @@ public static void main(final String[] args) { String[] arguments = new String[] {getConnectionStringSystemPropertyOrDefault()}; LOGGER.info("proper args={}, tour/example arguments={}", Arrays.toString(args), Arrays.toString(arguments)); List errors = Stream.of( - new ThrowingRunnable.Named("GraalVM native image substitutions", - Substitutions::assertUsed), + new ThrowingRunnable.Named(Substitutions.class, + () -> Substitutions.main(arguments)), new ThrowingRunnable.Named(DnsSpi.class, () -> DnsSpi.main(arguments)), new ThrowingRunnable.Named(gridfs.GridFSTour.class, diff --git a/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/Substitutions.java b/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/Substitutions.java new file mode 100644 index 00000000000..e21d6e6d0bb --- /dev/null +++ b/graalvm-native-image-app/src/main/com/mongodb/internal/graalvm/Substitutions.java @@ -0,0 +1,45 @@ +/* + * Copyright 2008-present MongoDB, Inc. + * + * 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 + * + * http://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.mongodb.internal.graalvm; + +import com.mongodb.UnixServerAddress; +import com.mongodb.internal.graalvm.substitution.UnixServerAddressSubstitution; + +import static com.mongodb.assertions.Assertions.fail; +import static org.graalvm.nativeimage.ImageInfo.inImageRuntimeCode; + +final class Substitutions { + public static void main(final String... args) { + assertUnixServerAddressSubstitution(); + } + + private static void assertUnixServerAddressSubstitution() { + try { + new UnixServerAddress("/tmp/mongodb-27017.sock"); + if (inImageRuntimeCode()) { + fail(String.format("%s was not applied", UnixServerAddressSubstitution.class)); + } + } catch (UnsupportedOperationException e) { + if (!inImageRuntimeCode()) { + throw e; + } + // expected in GraalVM + } + } + + private Substitutions() { + } +} From 77cb614873ee48c39820ef573c8d8aa60ddc57df Mon Sep 17 00:00:00 2001 From: Valentin Kovalenko Date: Sun, 21 Apr 2024 14:18:33 -0600 Subject: [PATCH 12/16] Remove `reactor.core`/`util` entries Entries were removed from `graalvm-native-image-app/src/main/resources/META-INF/native-image/reflect-config.json` as `NativeImageApp` works without them JAVA-5219 --- .../META-INF/native-image/reflect-config.json | 96 ------------------- 1 file changed, 96 deletions(-) diff --git a/graalvm-native-image-app/src/main/resources/META-INF/native-image/reflect-config.json b/graalvm-native-image-app/src/main/resources/META-INF/native-image/reflect-config.json index b99f29159a7..7b5464a4fa7 100644 --- a/graalvm-native-image-app/src/main/resources/META-INF/native-image/reflect-config.json +++ b/graalvm-native-image-app/src/main/resources/META-INF/native-image/reflect-config.json @@ -78,102 +78,6 @@ "queryAllDeclaredConstructors":true, "methods":[{"name":"","parameterTypes":[] }, {"name":"getAddress","parameterTypes":[] }, {"name":"getAge","parameterTypes":[] }, {"name":"getId","parameterTypes":[] }, {"name":"getName","parameterTypes":[] }, {"name":"setAddress","parameterTypes":["reactivestreams.tour.Address"] }, {"name":"setAge","parameterTypes":["int"] }, {"name":"setId","parameterTypes":["org.bson.types.ObjectId"] }, {"name":"setName","parameterTypes":["java.lang.String"] }] }, -{ - "name":"reactor.core.publisher.BaseSubscriber", - "fields":[{"name":"subscription"}] -}, -{ - "name":"reactor.core.publisher.FlatMapTracker", - "fields":[{"name":"size"}] -}, -{ - "name":"reactor.core.publisher.FluxConcatArray$ConcatArraySubscriber", - "fields":[{"name":"requested"}] -}, -{ - "name":"reactor.core.publisher.FluxCreate$BaseSink", - "fields":[{"name":"disposable"}, {"name":"requestConsumer"}, {"name":"requested"}] -}, -{ - "name":"reactor.core.publisher.FluxCreate$BufferAsyncSink", - "fields":[{"name":"wip"}] -}, -{ - "name":"reactor.core.publisher.FluxCreate$SerializedFluxSink", - "fields":[{"name":"error"}, {"name":"wip"}] -}, -{ - "name":"reactor.core.publisher.FluxDoFinally$DoFinallySubscriber", - "fields":[{"name":"once"}] -}, -{ - "name":"reactor.core.publisher.FluxFlatMap$FlatMapInner", - "fields":[{"name":"s"}] -}, -{ - "name":"reactor.core.publisher.FluxFlatMap$FlatMapMain", - "fields":[{"name":"error"}, {"name":"requested"}, {"name":"wip"}] -}, -{ - "name":"reactor.core.publisher.FluxIterable$IterableSubscription", - "fields":[{"name":"requested"}] -}, -{ - "name":"reactor.core.publisher.LambdaMonoSubscriber", - "fields":[{"name":"subscription"}] -}, -{ - "name":"reactor.core.publisher.LambdaSubscriber", - "fields":[{"name":"subscription"}] -}, -{ - "name":"reactor.core.publisher.MonoCallable$MonoCallableSubscription", - "fields":[{"name":"requestedOnce"}] -}, -{ - "name":"reactor.core.publisher.MonoCreate$DefaultMonoSink", - "fields":[{"name":"disposable"}, {"name":"requestConsumer"}, {"name":"state"}] -}, -{ - "name":"reactor.core.publisher.MonoFlatMap$FlatMapMain", - "fields":[{"name":"second"}] -}, -{ - "name":"reactor.core.publisher.MonoFlatMapMany$FlatMapManyMain", - "fields":[{"name":"inner"}, {"name":"requested"}] -}, -{ - "name":"reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain", - "fields":[{"name":"state"}] -}, -{ - "name":"reactor.core.publisher.MonoNext$NextSubscriber", - "fields":[{"name":"wip"}] -}, -{ - "name":"reactor.core.publisher.Operators$BaseFluxToMonoOperator", - "fields":[{"name":"state"}] -}, -{ - "name":"reactor.core.publisher.Operators$MultiSubscriptionSubscriber", - "fields":[{"name":"missedProduced"}, {"name":"missedRequested"}, {"name":"missedSubscription"}, {"name":"wip"}] -}, -{ - "name":"reactor.core.publisher.StrictSubscriber", - "fields":[{"name":"error"}, {"name":"requested"}, {"name":"s"}, {"name":"wip"}] -}, -{ - "name":"reactor.util.concurrent.MpscLinkedQueue", - "fields":[{"name":"consumerNode"}, {"name":"producerNode"}] -}, -{ - "name":"reactor.util.concurrent.MpscLinkedQueue$LinkedQueueNode", - "fields":[{"name":"next"}] -}, -{ - "name":"reactor.util.concurrent.SpscLinkedArrayQueue", - "fields":[{"name":"consumerIndex"}, {"name":"producerIndex"}] -}, { "name":"tour.Address", "allDeclaredFields":true, From a244a630745c2e0fc4874f857dfade3741f6199b Mon Sep 17 00:00:00 2001 From: Valentin Kovalenko Date: Tue, 30 Apr 2024 19:44:16 -0600 Subject: [PATCH 13/16] Improve the tracing agent configuration JAVA-5219 --- graalvm-native-image-app/build.gradle | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/graalvm-native-image-app/build.gradle b/graalvm-native-image-app/build.gradle index baf28986464..ea80039698f 100644 --- a/graalvm-native-image-app/build.gradle +++ b/graalvm-native-image-app/build.gradle @@ -40,9 +40,31 @@ graalvmNative { // The same is true about executing the `metadataCopy` Gradle task. // This may be a manifestation of an issue with the `org.graalvm.buildtools.native` plugin. enabled = false - defaultMode = 'standard' + defaultMode = 'direct' + def taskExecutedWithAgentAttached = 'run' + modes { + direct { + // see https://www.graalvm.org/latest/reference-manual/native-image/metadata/ExperimentalAgentOptions + options.add("config-output-dir=$buildDir/native/agent-output/$taskExecutedWithAgentAttached") + // `experimental-configuration-with-origins` produces + // `graalvm-native-image-app/build/native/agent-output/run/reflect-origins.txt` + // and similar files that explain the origin of each of the reachability metadata piece. + // However, for some reason, the actual reachability metadata is not generated when this option is enabled, + // so enable it manually if you need an explanation for a specific reachability metadata entry, + // and expect the build to fail. + // options.add('experimental-configuration-with-origins') + + // `experimental-class-define-support` does not seem to do what it is supposed to do. + // We need this option to work if we want to support `UnixServerAddress` in native image. + // Unfortunately, the tracing agent neither generates the metadata in + // `graalvm-native-image-app/src/main/resources/META-INF/native-image/proxy-config.json`, + // nor does it extract the bytecode of the generated classes to + // `graalvm-native-image-app/src/main/resources/META-INF/native-image/agent-extracted-predefined-classes`. + options.add('experimental-class-define-support') + } + } metadataCopy { - inputTaskNames.add('run') + inputTaskNames.add(taskExecutedWithAgentAttached) outputDirectories.add('src/main/resources/META-INF/native-image') mergeWithExisting = false } From 3bc66d2639df11dbfe28524853e12fc13031a11c Mon Sep 17 00:00:00 2001 From: Valentin Kovalenko Date: Wed, 1 May 2024 14:03:26 -0600 Subject: [PATCH 14/16] Properly rearrange metadata based on the metadata origins Goes to mongodb-crypt from driver-core/src/main/resources/META-INF/native-image/reflect-config.json: { "name":"boolean", "fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}] }, { "name":"com.sun.crypto.provider.AESCipher$General", "methods":[{"name":"","parameterTypes":[] }] }, { "name":"com.sun.crypto.provider.HmacCore$HmacSHA256", "methods":[{"name":"","parameterTypes":[] }] }, { "name":"com.sun.crypto.provider.HmacCore$HmacSHA512", "methods":[{"name":"","parameterTypes":[] }] }, { "name":"int", "fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}] }, { "name":"java.lang.Throwable", "methods":[{"name":"addSuppressed","parameterTypes":["java.lang.Throwable"] }] }, { "name":"java.lang.reflect.Method", "methods":[{"name":"isVarArgs","parameterTypes":[] }] }, { "name":"java.nio.Buffer" }, { "name":"long", "fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}] }, // NativePRNG also stays in driver-core { "name":"sun.security.provider.NativePRNG", "methods":[{"name":"","parameterTypes":[] }, {"name":"","parameterTypes":["java.security.SecureRandomParameters"] }] }, { "name":"sun.security.provider.SHA2$SHA256", "methods":[{"name":"","parameterTypes":[] }] }, { "name":"sun.security.provider.SHA5$SHA512", "methods":[{"name":"","parameterTypes":[] }] }, { "name":"void", "fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}] }, Goes to mongodb-crypt from graalvm-native-image-app/src/main/resources/META-INF/native-image/reflect-config.json { "name":"org.slf4j.Logger" }, Goes to graalvm-native-image-app/build/native/agent-output/run/reflect-config.json from driver-core/src/main/resources/META-INF/native-image/reflect-config.json { "name":"com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl", "methods":[{"name":"","parameterTypes":[] }] }, { "name":"java.io.FilePermission" }, { "name":"java.lang.RuntimePermission" }, { "name":"java.net.NetPermission" }, { "name":"java.net.SocketPermission" }, { "name":"java.net.URLPermission", "methods":[{"name":"","parameterTypes":["java.lang.String","java.lang.String"] }] }, { "name":"java.security.AllPermission" }, { "name":"java.security.SecurityPermission" }, { "name":"java.util.PropertyPermission" }, { "name":"java.util.concurrent.atomic.AtomicBoolean", "fields":[{"name":"value"}] }, { "name":"java.util.concurrent.atomic.AtomicReference", "fields":[{"name":"value"}] }, { "name":"javax.smartcardio.CardPermission" }, Goes to bson/src/main/resources/META-INF/native-image/reflect-config.json from driver-core/src/main/resources/META-INF/native-image/reflect-config.json { "name":"java.lang.Object", "queryAllDeclaredMethods":true }, Goes to bson/src/main/resources/META-INF/native-image/reflect-config.json from graalvm-native-image-app/src/main/resources/META-INF/native-image/reflect-config.json { "name":"org.slf4j.Logger" }, Goes to driver-core/src/main/resources/META-INF/native-image/reflect-config.json from graalvm-native-image-app/src/main/resources/META-INF/native-image/reflect-config.json { "name":"org.slf4j.Logger" }, JAVA-5219 --- .../META-INF/native-image/reflect-config.json | 5 -- .../META-INF/native-image/reflect-config.json | 5 -- .../META-INF/native-image/reflect-config.json | 5 -- .../META-INF/native-image/reflect-config.json | 9 +++ .../META-INF/native-image/reflect-config.json | 56 ++++--------------- .../META-INF/native-image/reflect-config.json | 39 ++++++++++++- 6 files changed, 59 insertions(+), 60 deletions(-) delete mode 100644 bson-kotlin/src/main/resources/META-INF/native-image/reflect-config.json delete mode 100644 bson-kotlinx/src/main/resources/META-INF/native-image/reflect-config.json delete mode 100644 bson-record-codec/src/main/resources/META-INF/native-image/reflect-config.json create mode 100644 bson/src/main/resources/META-INF/native-image/reflect-config.json diff --git a/bson-kotlin/src/main/resources/META-INF/native-image/reflect-config.json b/bson-kotlin/src/main/resources/META-INF/native-image/reflect-config.json deleted file mode 100644 index fc407c928bf..00000000000 --- a/bson-kotlin/src/main/resources/META-INF/native-image/reflect-config.json +++ /dev/null @@ -1,5 +0,0 @@ -[ -{ - "name":"org.bson.codecs.kotlin.DataClassCodecProvider" -} -] diff --git a/bson-kotlinx/src/main/resources/META-INF/native-image/reflect-config.json b/bson-kotlinx/src/main/resources/META-INF/native-image/reflect-config.json deleted file mode 100644 index 48b9c16c1a7..00000000000 --- a/bson-kotlinx/src/main/resources/META-INF/native-image/reflect-config.json +++ /dev/null @@ -1,5 +0,0 @@ -[ -{ - "name":"org.bson.codecs.kotlinx.KotlinSerializerCodecProvider" -} -] diff --git a/bson-record-codec/src/main/resources/META-INF/native-image/reflect-config.json b/bson-record-codec/src/main/resources/META-INF/native-image/reflect-config.json deleted file mode 100644 index d320243b4e7..00000000000 --- a/bson-record-codec/src/main/resources/META-INF/native-image/reflect-config.json +++ /dev/null @@ -1,5 +0,0 @@ -[ -{ - "name":"org.bson.codecs.record.RecordCodecProvider" -} -] diff --git a/bson/src/main/resources/META-INF/native-image/reflect-config.json b/bson/src/main/resources/META-INF/native-image/reflect-config.json new file mode 100644 index 00000000000..276ef9eda49 --- /dev/null +++ b/bson/src/main/resources/META-INF/native-image/reflect-config.json @@ -0,0 +1,9 @@ +[ +{ + "name":"java.lang.Object", + "queryAllDeclaredMethods":true +}, +{ + "name":"org.slf4j.Logger" +} +] diff --git a/driver-core/src/main/resources/META-INF/native-image/reflect-config.json b/driver-core/src/main/resources/META-INF/native-image/reflect-config.json index cd7ec099635..067e311f1a0 100644 --- a/driver-core/src/main/resources/META-INF/native-image/reflect-config.json +++ b/driver-core/src/main/resources/META-INF/native-image/reflect-config.json @@ -133,27 +133,13 @@ "fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}], "methods":[{"name":"","parameterTypes":[] }] }, -{ - "name":"com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl", - "methods":[{"name":"","parameterTypes":[] }] -}, { "name":"int", "fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}] }, -{ - "name":"java.io.FilePermission" -}, -{ - "name":"java.lang.Object", - "queryAllDeclaredMethods":true -}, { "name":"java.lang.Record" }, -{ - "name":"java.lang.RuntimePermission" -}, { "name":"java.lang.Thread", "fields":[{"name":"threadLocalRandomProbe"}] @@ -166,54 +152,24 @@ "name":"java.lang.reflect.Method", "methods":[{"name":"isVarArgs","parameterTypes":[] }] }, -{ - "name":"java.net.NetPermission" -}, { "name":"java.net.Socket", "methods":[{"name":"setOption","parameterTypes":["java.net.SocketOption","java.lang.Object"] }] }, -{ - "name":"java.net.SocketPermission" -}, -{ - "name":"java.net.URLPermission", - "methods":[{"name":"","parameterTypes":["java.lang.String","java.lang.String"] }] -}, { "name":"java.nio.Buffer" }, -{ - "name":"java.security.AllPermission" -}, { "name":"java.security.SecureRandomParameters" }, -{ - "name":"java.security.SecurityPermission" -}, -{ - "name":"java.util.PropertyPermission" -}, { "name":"java.util.concurrent.ForkJoinTask", "fields":[{"name":"aux"}, {"name":"status"}] }, -{ - "name":"java.util.concurrent.atomic.AtomicBoolean", - "fields":[{"name":"value"}] -}, -{ - "name":"java.util.concurrent.atomic.AtomicReference", - "fields":[{"name":"value"}] -}, { "name":"java.util.concurrent.atomic.Striped64", "fields":[{"name":"base"}, {"name":"cellsBusy"}] }, -{ - "name":"javax.smartcardio.CardPermission" -}, { "name":"jdk.internal.misc.Unsafe" }, @@ -244,5 +200,17 @@ { "name":"void", "fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}] +}, +{ + "name":"org.bson.codecs.kotlin.DataClassCodecProvider" +}, +{ + "name":"org.bson.codecs.kotlinx.KotlinSerializerCodecProvider" +}, +{ + "name":"org.bson.codecs.record.RecordCodecProvider" +}, +{ + "name":"org.slf4j.Logger" } ] diff --git a/graalvm-native-image-app/src/main/resources/META-INF/native-image/reflect-config.json b/graalvm-native-image-app/src/main/resources/META-INF/native-image/reflect-config.json index 7b5464a4fa7..609320d4645 100644 --- a/graalvm-native-image-app/src/main/resources/META-INF/native-image/reflect-config.json +++ b/graalvm-native-image-app/src/main/resources/META-INF/native-image/reflect-config.json @@ -62,7 +62,44 @@ "methods":[{"name":"valueOf","parameterTypes":["java.lang.String"] }] }, { - "name":"org.slf4j.Logger" + "name":"com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl", + "methods":[{"name":"","parameterTypes":[] }] +}, +{ + "name":"java.io.FilePermission" +}, +{ + "name":"java.lang.RuntimePermission" +}, +{ + "name":"java.net.NetPermission" +}, +{ + "name":"java.net.SocketPermission" +}, +{ + "name":"java.net.URLPermission", + "methods":[{"name":"","parameterTypes":["java.lang.String","java.lang.String"] }] +}, +{ + "name":"java.security.AllPermission" +}, +{ + "name":"java.security.SecurityPermission" +}, +{ + "name":"java.util.PropertyPermission" +}, +{ + "name":"java.util.concurrent.atomic.AtomicBoolean", + "fields":[{"name":"value"}] +}, +{ + "name":"java.util.concurrent.atomic.AtomicReference", + "fields":[{"name":"value"}] +}, +{ + "name":"javax.smartcardio.CardPermission" }, { "name":"reactivestreams.tour.Address", From faaba0405cda4ce2594aec39f0fbabf809344d1c Mon Sep 17 00:00:00 2001 From: Valentin Kovalenko Date: Thu, 19 Sep 2024 16:14:29 -0600 Subject: [PATCH 15/16] Remove GraalVM reachability metadata specific to `org.mongodb:mongodb-crypt` from ``:driver-core` JAVA-5408 --- .../META-INF/native-image/jni-config.json | 180 ------------------ .../META-INF/native-image/reflect-config.json | 125 ------------ 2 files changed, 305 deletions(-) delete mode 100644 driver-core/src/main/resources/META-INF/native-image/jni-config.json diff --git a/driver-core/src/main/resources/META-INF/native-image/jni-config.json b/driver-core/src/main/resources/META-INF/native-image/jni-config.json deleted file mode 100644 index 44e398cb556..00000000000 --- a/driver-core/src/main/resources/META-INF/native-image/jni-config.json +++ /dev/null @@ -1,180 +0,0 @@ -[ -{ - "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_crypto_fn", - "methods":[{"name":"crypt","parameterTypes":["com.sun.jna.Pointer","com.mongodb.crypt.capi.CAPI$mongocrypt_binary_t","com.mongodb.crypt.capi.CAPI$mongocrypt_binary_t","com.mongodb.crypt.capi.CAPI$mongocrypt_binary_t","com.mongodb.crypt.capi.CAPI$mongocrypt_binary_t","com.sun.jna.Pointer","com.mongodb.crypt.capi.CAPI$mongocrypt_status_t"] }] -}, -{ - "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_hash_fn", - "methods":[{"name":"hash","parameterTypes":["com.sun.jna.Pointer","com.mongodb.crypt.capi.CAPI$mongocrypt_binary_t","com.mongodb.crypt.capi.CAPI$mongocrypt_binary_t","com.mongodb.crypt.capi.CAPI$mongocrypt_status_t"] }] -}, -{ - "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_hmac_fn", - "methods":[{"name":"hmac","parameterTypes":["com.sun.jna.Pointer","com.mongodb.crypt.capi.CAPI$mongocrypt_binary_t","com.mongodb.crypt.capi.CAPI$mongocrypt_binary_t","com.mongodb.crypt.capi.CAPI$mongocrypt_binary_t","com.mongodb.crypt.capi.CAPI$mongocrypt_status_t"] }] -}, -{ - "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_log_fn_t", - "methods":[{"name":"log","parameterTypes":["int","com.mongodb.crypt.capi.CAPI$cstring","int","com.sun.jna.Pointer"] }] -}, -{ - "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_random_fn", - "methods":[{"name":"random","parameterTypes":["com.sun.jna.Pointer","com.mongodb.crypt.capi.CAPI$mongocrypt_binary_t","int","com.mongodb.crypt.capi.CAPI$mongocrypt_status_t"] }] -}, -{ - "name":"com.sun.jna.Callback" -}, -{ - "name":"com.sun.jna.CallbackReference", - "methods":[{"name":"getCallback","parameterTypes":["java.lang.Class","com.sun.jna.Pointer","boolean"] }, {"name":"getFunctionPointer","parameterTypes":["com.sun.jna.Callback","boolean"] }, {"name":"getNativeString","parameterTypes":["java.lang.Object","boolean"] }, {"name":"initializeThread","parameterTypes":["com.sun.jna.Callback","com.sun.jna.CallbackReference$AttachOptions"] }] -}, -{ - "name":"com.sun.jna.CallbackReference$AttachOptions" -}, -{ - "name":"com.sun.jna.FromNativeConverter", - "methods":[{"name":"nativeType","parameterTypes":[] }] -}, -{ - "name":"com.sun.jna.IntegerType", - "fields":[{"name":"value"}] -}, -{ - "name":"com.sun.jna.JNIEnv" -}, -{ - "name":"com.sun.jna.Native", - "methods":[{"name":"dispose","parameterTypes":[] }, {"name":"fromNative","parameterTypes":["com.sun.jna.FromNativeConverter","java.lang.Object","java.lang.reflect.Method"] }, {"name":"fromNative","parameterTypes":["java.lang.Class","java.lang.Object"] }, {"name":"fromNative","parameterTypes":["java.lang.reflect.Method","java.lang.Object"] }, {"name":"nativeType","parameterTypes":["java.lang.Class"] }, {"name":"toNative","parameterTypes":["com.sun.jna.ToNativeConverter","java.lang.Object"] }] -}, -{ - "name":"com.sun.jna.Native$ffi_callback", - "methods":[{"name":"invoke","parameterTypes":["long","long","long"] }] -}, -{ - "name":"com.sun.jna.NativeMapped", - "methods":[{"name":"toNative","parameterTypes":[] }] -}, -{ - "name":"com.sun.jna.Pointer", - "fields":[{"name":"peer"}], - "methods":[{"name":"","parameterTypes":["long"] }] -}, -{ - "name":"com.sun.jna.PointerType", - "fields":[{"name":"pointer"}] -}, -{ - "name":"com.sun.jna.Structure", - "fields":[{"name":"memory"}, {"name":"typeInfo"}], - "methods":[{"name":"autoRead","parameterTypes":[] }, {"name":"autoWrite","parameterTypes":[] }, {"name":"getTypeInfo","parameterTypes":[] }, {"name":"newInstance","parameterTypes":["java.lang.Class","long"] }] -}, -{ - "name":"com.sun.jna.Structure$ByValue" -}, -{ - "name":"com.sun.jna.Structure$FFIType$FFITypes", - "fields":[{"name":"ffi_type_double"}, {"name":"ffi_type_float"}, {"name":"ffi_type_longdouble"}, {"name":"ffi_type_pointer"}, {"name":"ffi_type_sint16"}, {"name":"ffi_type_sint32"}, {"name":"ffi_type_sint64"}, {"name":"ffi_type_sint8"}, {"name":"ffi_type_uint16"}, {"name":"ffi_type_uint32"}, {"name":"ffi_type_uint64"}, {"name":"ffi_type_uint8"}, {"name":"ffi_type_void"}] -}, -{ - "name":"com.sun.jna.WString", - "methods":[{"name":"","parameterTypes":["java.lang.String"] }] -}, -{ - "name":"java.lang.Boolean", - "fields":[{"name":"TYPE"}, {"name":"value"}], - "methods":[{"name":"","parameterTypes":["boolean"] }, {"name":"getBoolean","parameterTypes":["java.lang.String"] }] -}, -{ - "name":"java.lang.Byte", - "fields":[{"name":"TYPE"}, {"name":"value"}], - "methods":[{"name":"","parameterTypes":["byte"] }] -}, -{ - "name":"java.lang.Character", - "fields":[{"name":"TYPE"}, {"name":"value"}], - "methods":[{"name":"","parameterTypes":["char"] }] -}, -{ - "name":"java.lang.Class", - "methods":[{"name":"getComponentType","parameterTypes":[] }] -}, -{ - "name":"java.lang.Double", - "fields":[{"name":"TYPE"}, {"name":"value"}], - "methods":[{"name":"","parameterTypes":["double"] }] -}, -{ - "name":"java.lang.Float", - "fields":[{"name":"TYPE"}, {"name":"value"}], - "methods":[{"name":"","parameterTypes":["float"] }] -}, -{ - "name":"java.lang.Integer", - "fields":[{"name":"TYPE"}, {"name":"value"}], - "methods":[{"name":"","parameterTypes":["int"] }] -}, -{ - "name":"java.lang.Long", - "fields":[{"name":"TYPE"}, {"name":"value"}], - "methods":[{"name":"","parameterTypes":["long"] }] -}, -{ - "name":"java.lang.Object", - "methods":[{"name":"toString","parameterTypes":[] }] -}, -{ - "name":"java.lang.Short", - "fields":[{"name":"TYPE"}, {"name":"value"}], - "methods":[{"name":"","parameterTypes":["short"] }] -}, -{ - "name":"java.lang.String", - "methods":[{"name":"","parameterTypes":["byte[]"] }, {"name":"","parameterTypes":["byte[]","java.lang.String"] }, {"name":"getBytes","parameterTypes":[] }, {"name":"getBytes","parameterTypes":["java.lang.String"] }, {"name":"lastIndexOf","parameterTypes":["int"] }, {"name":"substring","parameterTypes":["int"] }, {"name":"toCharArray","parameterTypes":[] }] -}, -{ - "name":"java.lang.System", - "methods":[{"name":"getProperty","parameterTypes":["java.lang.String"] }, {"name":"setProperty","parameterTypes":["java.lang.String","java.lang.String"] }] -}, -{ - "name":"java.lang.UnsatisfiedLinkError", - "methods":[{"name":"","parameterTypes":["java.lang.String"] }] -}, -{ - "name":"java.lang.Void", - "fields":[{"name":"TYPE"}] -}, -{ - "name":"java.lang.reflect.Method", - "methods":[{"name":"getParameterTypes","parameterTypes":[] }, {"name":"getReturnType","parameterTypes":[] }] -}, -{ - "name":"java.nio.Buffer", - "methods":[{"name":"position","parameterTypes":[] }] -}, -{ - "name":"java.nio.ByteBuffer", - "methods":[{"name":"array","parameterTypes":[] }, {"name":"arrayOffset","parameterTypes":[] }] -}, -{ - "name":"java.nio.CharBuffer", - "methods":[{"name":"array","parameterTypes":[] }, {"name":"arrayOffset","parameterTypes":[] }] -}, -{ - "name":"java.nio.DoubleBuffer", - "methods":[{"name":"array","parameterTypes":[] }, {"name":"arrayOffset","parameterTypes":[] }] -}, -{ - "name":"java.nio.FloatBuffer", - "methods":[{"name":"array","parameterTypes":[] }, {"name":"arrayOffset","parameterTypes":[] }] -}, -{ - "name":"java.nio.IntBuffer", - "methods":[{"name":"array","parameterTypes":[] }, {"name":"arrayOffset","parameterTypes":[] }] -}, -{ - "name":"java.nio.LongBuffer", - "methods":[{"name":"array","parameterTypes":[] }, {"name":"arrayOffset","parameterTypes":[] }] -}, -{ - "name":"java.nio.ShortBuffer", - "methods":[{"name":"array","parameterTypes":[] }, {"name":"arrayOffset","parameterTypes":[] }] -} -] diff --git a/driver-core/src/main/resources/META-INF/native-image/reflect-config.json b/driver-core/src/main/resources/META-INF/native-image/reflect-config.json index 067e311f1a0..a9425acb8f8 100644 --- a/driver-core/src/main/resources/META-INF/native-image/reflect-config.json +++ b/driver-core/src/main/resources/META-INF/native-image/reflect-config.json @@ -39,104 +39,6 @@ "queryAllDeclaredConstructors":true, "methods":[{"name":"","parameterTypes":["java.util.List","org.bson.BsonDocument","java.util.List","org.bson.BsonDocument"] }] }, -{ - "name":"com.mongodb.crypt.capi.CAPI", - "allPublicFields":true, - "queryAllDeclaredMethods":true -}, -{ - "name":"com.mongodb.crypt.capi.CAPI$cstring", - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_binary_t", - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_crypto_fn", - "queryAllDeclaredMethods":true, - "queryAllPublicMethods":true -}, -{ - "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_ctx_t", - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_hash_fn", - "queryAllDeclaredMethods":true, - "queryAllPublicMethods":true -}, -{ - "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_hmac_fn", - "queryAllDeclaredMethods":true, - "queryAllPublicMethods":true -}, -{ - "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_kms_ctx_t", - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_log_fn_t", - "queryAllDeclaredMethods":true, - "queryAllPublicMethods":true -}, -{ - "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_random_fn", - "queryAllDeclaredMethods":true, - "queryAllPublicMethods":true -}, -{ - "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_status_t", - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"com.mongodb.crypt.capi.CAPI$mongocrypt_t", - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"boolean", - "fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}] -}, -{ - "name":"com.sun.crypto.provider.AESCipher$General", - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"com.sun.crypto.provider.HmacCore$HmacSHA256", - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"com.sun.crypto.provider.HmacCore$HmacSHA512", - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"com.sun.jna.CallbackProxy", - "methods":[{"name":"callback","parameterTypes":["java.lang.Object[]"] }] -}, -{ - "name":"com.sun.jna.Pointer", - "fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}] -}, -{ - "name":"com.sun.jna.Structure$FFIType", - "allDeclaredFields":true, - "queryAllPublicConstructors":true, - "fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}], - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"com.sun.jna.Structure$FFIType$size_t", - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"com.sun.jna.ptr.PointerByReference", - "fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}], - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"int", - "fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}] -}, { "name":"java.lang.Record" }, @@ -144,21 +46,10 @@ "name":"java.lang.Thread", "fields":[{"name":"threadLocalRandomProbe"}] }, -{ - "name":"java.lang.Throwable", - "methods":[{"name":"addSuppressed","parameterTypes":["java.lang.Throwable"] }] -}, -{ - "name":"java.lang.reflect.Method", - "methods":[{"name":"isVarArgs","parameterTypes":[] }] -}, { "name":"java.net.Socket", "methods":[{"name":"setOption","parameterTypes":["java.net.SocketOption","java.lang.Object"] }] }, -{ - "name":"java.nio.Buffer" -}, { "name":"java.security.SecureRandomParameters" }, @@ -177,10 +68,6 @@ "name":"jdk.net.ExtendedSocketOptions", "fields":[{"name":"TCP_KEEPCOUNT"}, {"name":"TCP_KEEPIDLE"}, {"name":"TCP_KEEPINTERVAL"}] }, -{ - "name":"long", - "fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}] -}, { "name":"sun.security.provider.NativePRNG", "methods":[{"name":"","parameterTypes":[] }, {"name":"","parameterTypes":["java.security.SecureRandomParameters"] }] @@ -189,18 +76,6 @@ "name":"sun.security.provider.SHA", "methods":[{"name":"","parameterTypes":[] }] }, -{ - "name":"sun.security.provider.SHA2$SHA256", - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"sun.security.provider.SHA5$SHA512", - "methods":[{"name":"","parameterTypes":[] }] -}, -{ - "name":"void", - "fields":[{"name":"OPTIONS"}, {"name":"STRING_ENCODING"}, {"name":"STRUCTURE_ALIGNMENT"}, {"name":"TYPE_MAPPER"}] -}, { "name":"org.bson.codecs.kotlin.DataClassCodecProvider" }, From 841f67b1118ca86b808da6982e52ce4f0085e992 Mon Sep 17 00:00:00 2001 From: Valentin Kovalenko Date: Fri, 20 Sep 2024 09:28:38 -0600 Subject: [PATCH 16/16] Move `NativePRNG`- and `SHA`-related metadata from `:driver-core` to `:bson` JAVA-5219 --- .../resources/META-INF/native-image/reflect-config.json | 8 ++++++++ .../resources/META-INF/native-image/reflect-config.json | 8 -------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bson/src/main/resources/META-INF/native-image/reflect-config.json b/bson/src/main/resources/META-INF/native-image/reflect-config.json index 276ef9eda49..dd27feda44d 100644 --- a/bson/src/main/resources/META-INF/native-image/reflect-config.json +++ b/bson/src/main/resources/META-INF/native-image/reflect-config.json @@ -3,6 +3,14 @@ "name":"java.lang.Object", "queryAllDeclaredMethods":true }, +{ + "name":"sun.security.provider.NativePRNG", + "methods":[{"name":"","parameterTypes":[] }, {"name":"","parameterTypes":["java.security.SecureRandomParameters"] }] +}, +{ + "name":"sun.security.provider.SHA", + "methods":[{"name":"","parameterTypes":[] }] +}, { "name":"org.slf4j.Logger" } diff --git a/driver-core/src/main/resources/META-INF/native-image/reflect-config.json b/driver-core/src/main/resources/META-INF/native-image/reflect-config.json index a9425acb8f8..9a89dbe1e1f 100644 --- a/driver-core/src/main/resources/META-INF/native-image/reflect-config.json +++ b/driver-core/src/main/resources/META-INF/native-image/reflect-config.json @@ -68,14 +68,6 @@ "name":"jdk.net.ExtendedSocketOptions", "fields":[{"name":"TCP_KEEPCOUNT"}, {"name":"TCP_KEEPIDLE"}, {"name":"TCP_KEEPINTERVAL"}] }, -{ - "name":"sun.security.provider.NativePRNG", - "methods":[{"name":"","parameterTypes":[] }, {"name":"","parameterTypes":["java.security.SecureRandomParameters"] }] -}, -{ - "name":"sun.security.provider.SHA", - "methods":[{"name":"","parameterTypes":[] }] -}, { "name":"org.bson.codecs.kotlin.DataClassCodecProvider" },