From 40745c38e81bd20a3f4352039cfef73e5d5e904c Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Wed, 22 Feb 2023 09:41:39 +0100 Subject: [PATCH 01/12] added SPI debug logs --- core/src/main/java/com/arangodb/async/ArangoDBAsync.java | 1 + .../java/com/arangodb/internal/InternalArangoDBBuilder.java | 3 ++- .../com/arangodb/internal/serde/InternalMapperProvider.java | 5 +++++ .../serde/jackson/internal/JacksonMapperProvider.java | 5 +++++ 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/arangodb/async/ArangoDBAsync.java b/core/src/main/java/com/arangodb/async/ArangoDBAsync.java index 98386c500..7d9ce542d 100644 --- a/core/src/main/java/com/arangodb/async/ArangoDBAsync.java +++ b/core/src/main/java/com/arangodb/async/ArangoDBAsync.java @@ -305,6 +305,7 @@ private AsyncProtocolProvider asyncProtocolProvider(Protocol protocol) { if (p.supportsProtocol(protocol)) { return p; } + LOG.debug("Required protocol ({}) not supported by ProtocolProvider: {}", protocol, p.getClass().getName()); } throw new ArangoDBException("No ProtocolProvider found for protocol: " + protocol); } diff --git a/core/src/main/java/com/arangodb/internal/InternalArangoDBBuilder.java b/core/src/main/java/com/arangodb/internal/InternalArangoDBBuilder.java index e482e405c..3ff36604b 100644 --- a/core/src/main/java/com/arangodb/internal/InternalArangoDBBuilder.java +++ b/core/src/main/java/com/arangodb/internal/InternalArangoDBBuilder.java @@ -44,7 +44,7 @@ * @author Mark Vollmary */ public abstract class InternalArangoDBBuilder> { - private static final Logger LOG = LoggerFactory.getLogger(InternalArangoDBBuilder.class); + protected static final Logger LOG = LoggerFactory.getLogger(InternalArangoDBBuilder.class); protected final ArangoConfig config = new ArangoConfig(); @SuppressWarnings("unchecked") @@ -295,6 +295,7 @@ protected ProtocolProvider protocolProvider(Protocol protocol) { if (p.supportsProtocol(protocol)) { return p; } + LOG.debug("Required protocol ({}) not supported by ProtocolProvider: {}", protocol, p.getClass().getName()); } throw new ArangoDBException("No ProtocolProvider found for protocol: " + protocol); } diff --git a/core/src/main/java/com/arangodb/internal/serde/InternalMapperProvider.java b/core/src/main/java/com/arangodb/internal/serde/InternalMapperProvider.java index 241e0893d..df088418e 100644 --- a/core/src/main/java/com/arangodb/internal/serde/InternalMapperProvider.java +++ b/core/src/main/java/com/arangodb/internal/serde/InternalMapperProvider.java @@ -4,11 +4,15 @@ import com.arangodb.ContentType; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.databind.ObjectMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.ServiceLoader; import java.util.function.Supplier; public interface InternalMapperProvider extends Supplier { + Logger LOG = LoggerFactory.getLogger(InternalMapperProvider.class); + static ObjectMapper of(final ContentType contentType) { String formatName; if (contentType == ContentType.JSON) { @@ -24,6 +28,7 @@ static ObjectMapper of(final ContentType contentType) { if(formatName.equals(jf.getFormatName())){ return new ObjectMapper(jf); } + LOG.debug("Required format ({}) not supported by JsonFactory: {}", formatName, jf.getClass().getName()); } throw new ArangoDBException("No JsonFactory found for content type: " + contentType); diff --git a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/JacksonMapperProvider.java b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/JacksonMapperProvider.java index 936192d0e..e4cca8d11 100644 --- a/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/JacksonMapperProvider.java +++ b/jackson-serde-json/src/main/java/com/arangodb/serde/jackson/internal/JacksonMapperProvider.java @@ -4,6 +4,8 @@ import com.arangodb.ContentType; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.databind.ObjectMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.ServiceLoader; import java.util.function.Supplier; @@ -12,6 +14,8 @@ * Not shaded in arangodb-java-driver-shaded. */ public interface JacksonMapperProvider extends Supplier { + Logger LOG = LoggerFactory.getLogger(JacksonMapperProvider.class); + static ObjectMapper of(final ContentType contentType) { String formatName; if (contentType == ContentType.JSON) { @@ -27,6 +31,7 @@ static ObjectMapper of(final ContentType contentType) { if(formatName.equals(jf.getFormatName())){ return new ObjectMapper(jf); } + LOG.debug("Required format ({}) not supported by JsonFactory: {}", formatName, jf.getClass().getName()); } throw new ArangoDBException("No JsonFactory found for content type: " + contentType); From 8d2c66b4730063fdbff6af4117eaa143de39f0de Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Wed, 22 Feb 2023 10:37:12 +0100 Subject: [PATCH 02/12] native image fix --- .../com.arangodb/arangodb-java-driver/native-image.properties | 2 ++ .../resources/META-INF/native-image/native-image.properties | 1 - .../arangodb-java-driver-shaded/native-image.properties | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/native-image.properties b/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/native-image.properties index 60c5b90d2..cd4fdf93b 100644 --- a/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/native-image.properties +++ b/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/native-image.properties @@ -2,6 +2,8 @@ Args=\ -H:ResourceConfigurationResources=${.}/resource-config.json \ -H:ReflectionConfigurationResources=${.}/reflect-config.json \ -H:SerializationConfigurationResources=${.}/serialization-config.json \ +--initialize-at-build-time=\ + org.slf4j \ --initialize-at-run-time=\ io.netty.handler.ssl.BouncyCastleAlpnSslUtils,\ io.netty.handler.codec.compression.ZstdOptions \ diff --git a/driver/src/test/resources/META-INF/native-image/native-image.properties b/driver/src/test/resources/META-INF/native-image/native-image.properties index b039368e7..2aa13d2f3 100644 --- a/driver/src/test/resources/META-INF/native-image/native-image.properties +++ b/driver/src/test/resources/META-INF/native-image/native-image.properties @@ -4,5 +4,4 @@ Args=\ -H:SerializationConfigurationResources=${.}/serialization-config.json \ --initialize-at-build-time=\ ch.qos.logback,\ - org.slf4j,\ org.junit.platform.engine.TestTag diff --git a/shaded/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver-shaded/native-image.properties b/shaded/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver-shaded/native-image.properties index ecbea5c1b..c7796d1fb 100644 --- a/shaded/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver-shaded/native-image.properties +++ b/shaded/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver-shaded/native-image.properties @@ -2,6 +2,8 @@ Args=\ -H:ResourceConfigurationResources=${.}/resource-config.json \ -H:ReflectionConfigurationResources=${.}/reflect-config.json,${.}/netty-reflect-config.json \ -H:SerializationConfigurationResources=${.}/serialization-config.json \ +--initialize-at-build-time=\ + org.slf4j \ --initialize-at-run-time=\ com.arangodb.shaded.netty.handler.ssl.BouncyCastleAlpnSslUtils,\ com.arangodb.shaded.netty.handler.codec.compression.ZstdOptions \ From 1b52f27ee67b2c9d58374a9f08f56f221fdd0fee Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Wed, 22 Feb 2023 14:44:40 +0100 Subject: [PATCH 03/12] fix SPI in native image --- driver/pom.xml | 4 ++-- .../native-image.properties | 6 +++--- .../reflect-config-spi.json | 11 ++++++++++ .../http-protocol/native-image.properties | 3 +++ .../http-protocol/reflect-config-spi.json | 11 ++++++++++ .../http-protocol/resource-config-spi.json | 10 ++++++++++ .../native-image.properties | 3 +++ .../reflect-config-spi.json | 11 ++++++++++ .../resource-config-spi.json | 10 ++++++++++ .../json-serde/native-image.properties | 3 +++ .../json-serde/reflect-config-spi.json | 11 ++++++++++ .../json-serde/resource-config-spi.json | 10 ++++++++++ pom.xml | 2 +- .../vst-protocol/native-image.properties | 3 +++ .../vst-protocol/reflect-config-spi.json | 20 +++++++++++++++++++ .../vst-protocol/resource-config-spi.json | 13 ++++++++++++ 16 files changed, 125 insertions(+), 6 deletions(-) create mode 100644 driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/reflect-config-spi.json create mode 100644 http/src/main/resources/META-INF/native-image/com.arangodb/http-protocol/native-image.properties create mode 100644 http/src/main/resources/META-INF/native-image/com.arangodb/http-protocol/reflect-config-spi.json create mode 100644 http/src/main/resources/META-INF/native-image/com.arangodb/http-protocol/resource-config-spi.json create mode 100644 jackson-serde-json/src/main/resources/META-INF/native-image/com.arangodb/jackson-serde-json/native-image.properties create mode 100644 jackson-serde-json/src/main/resources/META-INF/native-image/com.arangodb/jackson-serde-json/reflect-config-spi.json create mode 100644 jackson-serde-json/src/main/resources/META-INF/native-image/com.arangodb/jackson-serde-json/resource-config-spi.json create mode 100644 jsonb-serde/src/main/resources/META-INF/native-image/com.arangodb/json-serde/native-image.properties create mode 100644 jsonb-serde/src/main/resources/META-INF/native-image/com.arangodb/json-serde/reflect-config-spi.json create mode 100644 jsonb-serde/src/main/resources/META-INF/native-image/com.arangodb/json-serde/resource-config-spi.json create mode 100644 vst/src/main/resources/META-INF/native-image/com.arangodb/vst-protocol/native-image.properties create mode 100644 vst/src/main/resources/META-INF/native-image/com.arangodb/vst-protocol/reflect-config-spi.json create mode 100644 vst/src/main/resources/META-INF/native-image/com.arangodb/vst-protocol/resource-config-spi.json diff --git a/driver/pom.xml b/driver/pom.xml index 3481759bd..ee59d9e42 100644 --- a/driver/pom.xml +++ b/driver/pom.xml @@ -138,12 +138,12 @@ com.arangodb jackson-serde-vpack - test + true com.arangodb vst-protocol - test + true org.reflections diff --git a/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/native-image.properties b/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/native-image.properties index cd4fdf93b..3a1fa6818 100644 --- a/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/native-image.properties +++ b/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/native-image.properties @@ -1,11 +1,11 @@ Args=\ -H:ResourceConfigurationResources=${.}/resource-config.json \ --H:ReflectionConfigurationResources=${.}/reflect-config.json \ +-H:ReflectionConfigurationResources=${.}/reflect-config.json,${.}/reflect-config-spi.json \ -H:SerializationConfigurationResources=${.}/serialization-config.json \ --initialize-at-build-time=\ org.slf4j \ --initialize-at-run-time=\ - io.netty.handler.ssl.BouncyCastleAlpnSslUtils,\ - io.netty.handler.codec.compression.ZstdOptions \ + io.netty.handler.ssl.BouncyCastleAlpnSslUtils,\ + io.netty.handler.codec.compression.ZstdOptions \ -Dio.netty.noUnsafe=true \ -Dio.netty.leakDetection.level=DISABLED diff --git a/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/reflect-config-spi.json b/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/reflect-config-spi.json new file mode 100644 index 000000000..cf082f1dd --- /dev/null +++ b/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/reflect-config-spi.json @@ -0,0 +1,11 @@ +[ + { + "name": "com.fasterxml.jackson.core.JsonFactory", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + } +] diff --git a/http/src/main/resources/META-INF/native-image/com.arangodb/http-protocol/native-image.properties b/http/src/main/resources/META-INF/native-image/com.arangodb/http-protocol/native-image.properties new file mode 100644 index 000000000..f6d4bf39a --- /dev/null +++ b/http/src/main/resources/META-INF/native-image/com.arangodb/http-protocol/native-image.properties @@ -0,0 +1,3 @@ +Args=\ +-H:ResourceConfigurationResources=${.}/resource-config-spi.json \ +-H:ReflectionConfigurationResources=${.}/reflect-config-spi.json diff --git a/http/src/main/resources/META-INF/native-image/com.arangodb/http-protocol/reflect-config-spi.json b/http/src/main/resources/META-INF/native-image/com.arangodb/http-protocol/reflect-config-spi.json new file mode 100644 index 000000000..be5c8f170 --- /dev/null +++ b/http/src/main/resources/META-INF/native-image/com.arangodb/http-protocol/reflect-config-spi.json @@ -0,0 +1,11 @@ +[ + { + "name": "com.arangodb.http.HttpProtocolProvider", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + } +] diff --git a/http/src/main/resources/META-INF/native-image/com.arangodb/http-protocol/resource-config-spi.json b/http/src/main/resources/META-INF/native-image/com.arangodb/http-protocol/resource-config-spi.json new file mode 100644 index 000000000..9037d85e5 --- /dev/null +++ b/http/src/main/resources/META-INF/native-image/com.arangodb/http-protocol/resource-config-spi.json @@ -0,0 +1,10 @@ +{ + "resources": { + "includes": [ + { + "pattern": "META-INF/services/com.arangodb.internal.net.ProtocolProvider" + } + ] + }, + "bundles": [] +} diff --git a/jackson-serde-json/src/main/resources/META-INF/native-image/com.arangodb/jackson-serde-json/native-image.properties b/jackson-serde-json/src/main/resources/META-INF/native-image/com.arangodb/jackson-serde-json/native-image.properties new file mode 100644 index 000000000..f6d4bf39a --- /dev/null +++ b/jackson-serde-json/src/main/resources/META-INF/native-image/com.arangodb/jackson-serde-json/native-image.properties @@ -0,0 +1,3 @@ +Args=\ +-H:ResourceConfigurationResources=${.}/resource-config-spi.json \ +-H:ReflectionConfigurationResources=${.}/reflect-config-spi.json diff --git a/jackson-serde-json/src/main/resources/META-INF/native-image/com.arangodb/jackson-serde-json/reflect-config-spi.json b/jackson-serde-json/src/main/resources/META-INF/native-image/com.arangodb/jackson-serde-json/reflect-config-spi.json new file mode 100644 index 000000000..cee7b71af --- /dev/null +++ b/jackson-serde-json/src/main/resources/META-INF/native-image/com.arangodb/jackson-serde-json/reflect-config-spi.json @@ -0,0 +1,11 @@ +[ + { + "name": "com.arangodb.serde.jackson.JacksonSerdeProvider", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + } +] diff --git a/jackson-serde-json/src/main/resources/META-INF/native-image/com.arangodb/jackson-serde-json/resource-config-spi.json b/jackson-serde-json/src/main/resources/META-INF/native-image/com.arangodb/jackson-serde-json/resource-config-spi.json new file mode 100644 index 000000000..520213dcf --- /dev/null +++ b/jackson-serde-json/src/main/resources/META-INF/native-image/com.arangodb/jackson-serde-json/resource-config-spi.json @@ -0,0 +1,10 @@ +{ + "resources": { + "includes": [ + { + "pattern": "META-INF/services/com.arangodb.serde.ArangoSerdeProvider" + } + ] + }, + "bundles": [] +} diff --git a/jsonb-serde/src/main/resources/META-INF/native-image/com.arangodb/json-serde/native-image.properties b/jsonb-serde/src/main/resources/META-INF/native-image/com.arangodb/json-serde/native-image.properties new file mode 100644 index 000000000..f6d4bf39a --- /dev/null +++ b/jsonb-serde/src/main/resources/META-INF/native-image/com.arangodb/json-serde/native-image.properties @@ -0,0 +1,3 @@ +Args=\ +-H:ResourceConfigurationResources=${.}/resource-config-spi.json \ +-H:ReflectionConfigurationResources=${.}/reflect-config-spi.json diff --git a/jsonb-serde/src/main/resources/META-INF/native-image/com.arangodb/json-serde/reflect-config-spi.json b/jsonb-serde/src/main/resources/META-INF/native-image/com.arangodb/json-serde/reflect-config-spi.json new file mode 100644 index 000000000..5a63b3c30 --- /dev/null +++ b/jsonb-serde/src/main/resources/META-INF/native-image/com.arangodb/json-serde/reflect-config-spi.json @@ -0,0 +1,11 @@ +[ + { + "name": "com.arangodb.serde.jsonb.JsonbSerdeProvider", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + } +] diff --git a/jsonb-serde/src/main/resources/META-INF/native-image/com.arangodb/json-serde/resource-config-spi.json b/jsonb-serde/src/main/resources/META-INF/native-image/com.arangodb/json-serde/resource-config-spi.json new file mode 100644 index 000000000..520213dcf --- /dev/null +++ b/jsonb-serde/src/main/resources/META-INF/native-image/com.arangodb/json-serde/resource-config-spi.json @@ -0,0 +1,10 @@ +{ + "resources": { + "includes": [ + { + "pattern": "META-INF/services/com.arangodb.serde.ArangoSerdeProvider" + } + ] + }, + "bundles": [] +} diff --git a/pom.xml b/pom.xml index 24508f88f..22ce8fb6b 100644 --- a/pom.xml +++ b/pom.xml @@ -156,7 +156,7 @@ com.arangodb jackson-dataformat-velocypack - 4.0.0 + 4.0.1 org.slf4j diff --git a/vst/src/main/resources/META-INF/native-image/com.arangodb/vst-protocol/native-image.properties b/vst/src/main/resources/META-INF/native-image/com.arangodb/vst-protocol/native-image.properties new file mode 100644 index 000000000..f6d4bf39a --- /dev/null +++ b/vst/src/main/resources/META-INF/native-image/com.arangodb/vst-protocol/native-image.properties @@ -0,0 +1,3 @@ +Args=\ +-H:ResourceConfigurationResources=${.}/resource-config-spi.json \ +-H:ReflectionConfigurationResources=${.}/reflect-config-spi.json diff --git a/vst/src/main/resources/META-INF/native-image/com.arangodb/vst-protocol/reflect-config-spi.json b/vst/src/main/resources/META-INF/native-image/com.arangodb/vst-protocol/reflect-config-spi.json new file mode 100644 index 000000000..c582132f6 --- /dev/null +++ b/vst/src/main/resources/META-INF/native-image/com.arangodb/vst-protocol/reflect-config-spi.json @@ -0,0 +1,20 @@ +[ + { + "name": "com.arangodb.vst.VstAsyncProtocolProvider", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "com.arangodb.vst.VstProtocolProvider", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + } +] diff --git a/vst/src/main/resources/META-INF/native-image/com.arangodb/vst-protocol/resource-config-spi.json b/vst/src/main/resources/META-INF/native-image/com.arangodb/vst-protocol/resource-config-spi.json new file mode 100644 index 000000000..b4ecc2447 --- /dev/null +++ b/vst/src/main/resources/META-INF/native-image/com.arangodb/vst-protocol/resource-config-spi.json @@ -0,0 +1,13 @@ +{ + "resources": { + "includes": [ + { + "pattern": "META-INF/services/com.arangodb.internal.net.AsyncProtocolProvider" + }, + { + "pattern": "META-INF/services/com.arangodb.internal.net.ProtocolProvider" + } + ] + }, + "bundles": [] +} From 25d2c0a100c66158411113f992b7256f2903ff09 Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Thu, 23 Feb 2023 17:39:41 +0100 Subject: [PATCH 04/12] fix MP-config in native image --- .../arangodb-java-driver/native-image.properties | 2 +- .../reflect-config-mp-config.json | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/reflect-config-mp-config.json diff --git a/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/native-image.properties b/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/native-image.properties index 3a1fa6818..87b367583 100644 --- a/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/native-image.properties +++ b/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/native-image.properties @@ -1,6 +1,6 @@ Args=\ -H:ResourceConfigurationResources=${.}/resource-config.json \ --H:ReflectionConfigurationResources=${.}/reflect-config.json,${.}/reflect-config-spi.json \ +-H:ReflectionConfigurationResources=${.}/reflect-config.json,${.}/reflect-config-spi.json,${.}/reflect-config-mp-config.json \ -H:SerializationConfigurationResources=${.}/serialization-config.json \ --initialize-at-build-time=\ org.slf4j \ diff --git a/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/reflect-config-mp-config.json b/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/reflect-config-mp-config.json new file mode 100644 index 000000000..84892c37d --- /dev/null +++ b/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/reflect-config-mp-config.json @@ -0,0 +1,13 @@ +[ + { + "name": "com.arangodb.config.HostDescription", + "methods": [ + { + "name": "parse", + "parameterTypes": [ + "java.lang.CharSequence" + ] + } + ] + } +] \ No newline at end of file From 82e1c1af2a00ef92c6ebb013ccdb350aeb151783 Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Sat, 25 Feb 2023 22:03:36 +0100 Subject: [PATCH 05/12] fix SPI in native image --- .../native-image.properties | 2 +- .../resource-config-spi.json | 10 ++++++++++ shaded/pom.xml | 3 ++- .../native-image.properties | 4 ++-- .../reflect-config-mp-config.json | 13 ++++++++++++ .../reflect-config-spi.json | 20 +++++++++++++++++++ .../resource-config-spi.json | 10 ++++++++++ 7 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/resource-config-spi.json create mode 100644 shaded/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver-shaded/reflect-config-mp-config.json create mode 100644 shaded/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver-shaded/reflect-config-spi.json create mode 100644 shaded/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver-shaded/resource-config-spi.json diff --git a/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/native-image.properties b/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/native-image.properties index 87b367583..aeaee72e6 100644 --- a/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/native-image.properties +++ b/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/native-image.properties @@ -1,5 +1,5 @@ Args=\ --H:ResourceConfigurationResources=${.}/resource-config.json \ +-H:ResourceConfigurationResources=${.}/resource-config.json,${.}/resource-config-spi.json \ -H:ReflectionConfigurationResources=${.}/reflect-config.json,${.}/reflect-config-spi.json,${.}/reflect-config-mp-config.json \ -H:SerializationConfigurationResources=${.}/serialization-config.json \ --initialize-at-build-time=\ diff --git a/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/resource-config-spi.json b/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/resource-config-spi.json new file mode 100644 index 000000000..7fb12eab0 --- /dev/null +++ b/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/resource-config-spi.json @@ -0,0 +1,10 @@ +{ + "resources": { + "includes": [ + { + "pattern": "META-INF/services/com.fasterxml.jackson.core.JsonFactory" + } + ] + }, + "bundles": [] +} diff --git a/shaded/pom.xml b/shaded/pom.xml index 40db119e9..a0ec6429f 100644 --- a/shaded/pom.xml +++ b/shaded/pom.xml @@ -94,7 +94,8 @@ com.arangodb:vst-protocol - META-INF/** + META-INF/MANIFEST.MF + META-INF/services/** diff --git a/shaded/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver-shaded/native-image.properties b/shaded/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver-shaded/native-image.properties index c7796d1fb..9ff995ecd 100644 --- a/shaded/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver-shaded/native-image.properties +++ b/shaded/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver-shaded/native-image.properties @@ -1,6 +1,6 @@ Args=\ --H:ResourceConfigurationResources=${.}/resource-config.json \ --H:ReflectionConfigurationResources=${.}/reflect-config.json,${.}/netty-reflect-config.json \ +-H:ResourceConfigurationResources=${.}/resource-config.json,${.}/resource-config-spi.json \ +-H:ReflectionConfigurationResources=${.}/reflect-config.json,${.}/reflect-config-spi.json,${.}/reflect-config-mp-config.json,${.}/netty-reflect-config.json \ -H:SerializationConfigurationResources=${.}/serialization-config.json \ --initialize-at-build-time=\ org.slf4j \ diff --git a/shaded/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver-shaded/reflect-config-mp-config.json b/shaded/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver-shaded/reflect-config-mp-config.json new file mode 100644 index 000000000..84892c37d --- /dev/null +++ b/shaded/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver-shaded/reflect-config-mp-config.json @@ -0,0 +1,13 @@ +[ + { + "name": "com.arangodb.config.HostDescription", + "methods": [ + { + "name": "parse", + "parameterTypes": [ + "java.lang.CharSequence" + ] + } + ] + } +] \ No newline at end of file diff --git a/shaded/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver-shaded/reflect-config-spi.json b/shaded/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver-shaded/reflect-config-spi.json new file mode 100644 index 000000000..e14d4bf2e --- /dev/null +++ b/shaded/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver-shaded/reflect-config-spi.json @@ -0,0 +1,20 @@ +[ + { + "name": "com.arangodb.shaded.fasterxml.jackson.core.JsonFactory", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "com.arangodb.shaded.jackson.dataformat.velocypack.VPackFactory", + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + } +] diff --git a/shaded/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver-shaded/resource-config-spi.json b/shaded/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver-shaded/resource-config-spi.json new file mode 100644 index 000000000..43406b15c --- /dev/null +++ b/shaded/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver-shaded/resource-config-spi.json @@ -0,0 +1,10 @@ +{ + "resources": { + "includes": [ + { + "pattern": "META-INF/services/com.arangodb.shaded.fasterxml.jackson.core.JsonFactory" + } + ] + }, + "bundles": [] +} From 0f7a7d65da7331018d0598b5078e953311e596e2 Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Fri, 3 Mar 2023 16:44:54 +0100 Subject: [PATCH 06/12] native tests with --link-at-build-time --- .../native-image.properties | 4 +- .../com/arangodb/example/FirstProject.java | 3 +- .../src/test/java/graal/EmptyByteBufStub.java | 33 + .../HttpContentCompressorSubstitutions.java | 29 + .../test/java/graal/NettySubstitutions.java | 605 ++++++++++++++++++ .../test/java/graal/VertxSubstitutions.java | 195 ++++++ .../test/java/graal/ZLibSubstitutions.java | 66 ++ .../UnicodeUtilsTest.java | 0 .../native-image/native-image.properties | 1 - .../META-INF/native-image/reflect-config.json | 74 --- driver/src/test/resources/logback-test.xml | 18 - .../test/resources/simplelogger.properties | 10 + pom.xml | 27 +- resilience-tests/pom.xml | 5 + 14 files changed, 969 insertions(+), 101 deletions(-) create mode 100644 driver/src/test/java/graal/EmptyByteBufStub.java create mode 100644 driver/src/test/java/graal/HttpContentCompressorSubstitutions.java create mode 100644 driver/src/test/java/graal/NettySubstitutions.java create mode 100644 driver/src/test/java/graal/VertxSubstitutions.java create mode 100644 driver/src/test/java/graal/ZLibSubstitutions.java rename driver/src/test/java/{graalvm => unicode}/UnicodeUtilsTest.java (100%) delete mode 100644 driver/src/test/resources/logback-test.xml create mode 100644 driver/src/test/resources/simplelogger.properties diff --git a/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/native-image.properties b/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/native-image.properties index aeaee72e6..5f368dc7b 100644 --- a/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/native-image.properties +++ b/driver/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver/native-image.properties @@ -6,6 +6,8 @@ Args=\ org.slf4j \ --initialize-at-run-time=\ io.netty.handler.ssl.BouncyCastleAlpnSslUtils,\ - io.netty.handler.codec.compression.ZstdOptions \ + io.netty.handler.codec.compression.ZstdOptions,\ + io.netty.handler.codec.compression.BrotliOptions,\ + io.netty.handler.codec.compression.Brotli \ -Dio.netty.noUnsafe=true \ -Dio.netty.leakDetection.level=DISABLED diff --git a/driver/src/test/java/com/arangodb/example/FirstProject.java b/driver/src/test/java/com/arangodb/example/FirstProject.java index 454bfabc7..cd0f7fc2c 100644 --- a/driver/src/test/java/com/arangodb/example/FirstProject.java +++ b/driver/src/test/java/com/arangodb/example/FirstProject.java @@ -1,6 +1,7 @@ package com.arangodb.example; import com.arangodb.*; +import com.arangodb.config.ArangoConfigProperties; import com.arangodb.entity.BaseDocument; import com.arangodb.entity.CollectionEntity; import com.fasterxml.jackson.databind.JsonNode; @@ -12,7 +13,7 @@ public class FirstProject { public static void main(final String[] args) { - final ArangoDB arangoDB = new ArangoDB.Builder().user("root").build(); + final ArangoDB arangoDB = new ArangoDB.Builder().loadProperties(ArangoConfigProperties.fromFile()).user("root").build(); // create database final DbName dbName = DbName.of("mydb"); diff --git a/driver/src/test/java/graal/EmptyByteBufStub.java b/driver/src/test/java/graal/EmptyByteBufStub.java new file mode 100644 index 000000000..2f46d7c5c --- /dev/null +++ b/driver/src/test/java/graal/EmptyByteBufStub.java @@ -0,0 +1,33 @@ +package graal; + +import io.netty.util.internal.PlatformDependent; + +import java.nio.ByteBuffer; + +public final class EmptyByteBufStub { + private static final ByteBuffer EMPTY_BYTE_BUFFER = ByteBuffer.allocateDirect(0); + private static final long EMPTY_BYTE_BUFFER_ADDRESS; + + static { + long emptyByteBufferAddress = 0; + try { + if (PlatformDependent.hasUnsafe()) { + emptyByteBufferAddress = PlatformDependent.directBufferAddress(EMPTY_BYTE_BUFFER); + } + } catch (Throwable t) { + // Ignore + } + EMPTY_BYTE_BUFFER_ADDRESS = emptyByteBufferAddress; + } + + public static ByteBuffer emptyByteBuffer() { + return EMPTY_BYTE_BUFFER; + } + + public static long emptyByteBufferAddress() { + return EMPTY_BYTE_BUFFER_ADDRESS; + } + + private EmptyByteBufStub() { + } +} diff --git a/driver/src/test/java/graal/HttpContentCompressorSubstitutions.java b/driver/src/test/java/graal/HttpContentCompressorSubstitutions.java new file mode 100644 index 000000000..92bed76be --- /dev/null +++ b/driver/src/test/java/graal/HttpContentCompressorSubstitutions.java @@ -0,0 +1,29 @@ +package graal; + +import com.oracle.svm.core.annotate.Substitute; +import com.oracle.svm.core.annotate.TargetClass; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; + +public class HttpContentCompressorSubstitutions { + + @TargetClass(className = "io.netty.handler.codec.compression.ZstdEncoder") + public static final class ZstdEncoderFactorySubstitution { + + @Substitute + protected ByteBuf allocateBuffer(ChannelHandlerContext ctx, ByteBuf msg, boolean preferDirect) throws Exception { + throw new UnsupportedOperationException(); + } + + @Substitute + protected void encode(ChannelHandlerContext ctx, ByteBuf in, ByteBuf out) { + throw new UnsupportedOperationException(); + } + + @Substitute + public void flush(final ChannelHandlerContext ctx) { + throw new UnsupportedOperationException(); + } + } + +} diff --git a/driver/src/test/java/graal/NettySubstitutions.java b/driver/src/test/java/graal/NettySubstitutions.java new file mode 100644 index 000000000..899d03616 --- /dev/null +++ b/driver/src/test/java/graal/NettySubstitutions.java @@ -0,0 +1,605 @@ +package graal; + +import com.oracle.svm.core.annotate.Alias; +import com.oracle.svm.core.annotate.RecomputeFieldValue; +import com.oracle.svm.core.annotate.RecomputeFieldValue.Kind; +import com.oracle.svm.core.annotate.Substitute; +import com.oracle.svm.core.annotate.TargetClass; +import io.netty.bootstrap.AbstractBootstrapConfig; +import io.netty.bootstrap.ChannelFactory; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; +import io.netty.channel.*; +import io.netty.channel.embedded.EmbeddedChannel; +import io.netty.handler.codec.compression.ZlibCodecFactory; +import io.netty.handler.codec.compression.ZlibWrapper; +import io.netty.handler.codec.http.HttpHeaderValues; +import io.netty.handler.codec.http2.Http2Exception; +import io.netty.handler.ssl.*; +import io.netty.handler.ssl.ApplicationProtocolConfig.SelectorFailureBehavior; +import io.netty.util.concurrent.GlobalEventExecutor; +import io.netty.util.internal.logging.InternalLoggerFactory; +import io.netty.util.internal.logging.JdkLoggerFactory; + +import javax.crypto.NoSuchPaddingException; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLException; +import javax.net.ssl.TrustManagerFactory; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; +import java.security.*; +import java.security.cert.X509Certificate; +import java.security.spec.InvalidKeySpecException; +import java.util.*; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.function.BooleanSupplier; + +import static io.netty.handler.codec.http.HttpHeaderValues.*; + +/** + * This substitution avoid having loggers added to the build + */ +@TargetClass(className = "io.netty.util.internal.logging.InternalLoggerFactory") +final class Target_io_netty_util_internal_logging_InternalLoggerFactory { + + @Substitute + private static InternalLoggerFactory newDefaultFactory(String name) { + return JdkLoggerFactory.INSTANCE; + } +} + +// SSL +// This whole section is mostly about removing static analysis references to openssl/tcnative + +@TargetClass(className = "io.netty.handler.ssl.SslProvider") +final class Target_io_netty_handler_ssl_SslProvider { + @Substitute + public static boolean isAlpnSupported(final SslProvider provider) { + switch (provider) { + case JDK: + return Target_io_netty_handler_ssl_JdkAlpnApplicationProtocolNegotiator.isAlpnSupported(); + case OPENSSL: + case OPENSSL_REFCNT: + return false; + default: + throw new Error("SslProvider unsupported: " + provider); + } + } +} + +@TargetClass(className = "io.netty.handler.ssl.JdkAlpnApplicationProtocolNegotiator") +final class Target_io_netty_handler_ssl_JdkAlpnApplicationProtocolNegotiator { + @Alias + static boolean isAlpnSupported() { + return true; + } +} + +/** + * Hardcode io.netty.handler.ssl.OpenSsl as non-available + */ +@TargetClass(className = "io.netty.handler.ssl.OpenSsl") +final class Target_io_netty_handler_ssl_OpenSsl { + + @Alias + @RecomputeFieldValue(kind = Kind.FromAlias) + private static Throwable UNAVAILABILITY_CAUSE = new RuntimeException("OpenSsl unsupported!"); + + @Alias + @RecomputeFieldValue(kind = Kind.FromAlias) + static List DEFAULT_CIPHERS = Collections.emptyList(); + + @Alias + @RecomputeFieldValue(kind = Kind.FromAlias) + static Set AVAILABLE_CIPHER_SUITES = Collections.emptySet(); + + @Alias + @RecomputeFieldValue(kind = Kind.FromAlias) + private static Set AVAILABLE_OPENSSL_CIPHER_SUITES = Collections.emptySet(); + + @Alias + @RecomputeFieldValue(kind = Kind.FromAlias) + private static Set AVAILABLE_JAVA_CIPHER_SUITES = Collections.emptySet(); + + @Alias + @RecomputeFieldValue(kind = Kind.FromAlias) + private static boolean SUPPORTS_KEYMANAGER_FACTORY = false; + + @Alias + @RecomputeFieldValue(kind = Kind.FromAlias) + private static boolean SUPPORTS_OCSP = false; + + @Alias + @RecomputeFieldValue(kind = Kind.FromAlias) + static Set SUPPORTED_PROTOCOLS_SET = Collections.emptySet(); + + @Substitute + public static boolean isAvailable() { + return false; + } + + @Substitute + public static int version() { + return -1; + } + + @Substitute + public static String versionString() { + return null; + } + + @Substitute + public static boolean isCipherSuiteAvailable(String cipherSuite) { + return false; + } +} + +@TargetClass(className = "io.netty.handler.ssl.JdkSslServerContext") +final class Target_io_netty_handler_ssl_JdkSslServerContext { + + @Alias + Target_io_netty_handler_ssl_JdkSslServerContext(Provider provider, + X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory, + X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, + KeyManagerFactory keyManagerFactory, Iterable ciphers, CipherSuiteFilter cipherFilter, + ApplicationProtocolConfig apn, long sessionCacheSize, long sessionTimeout, + ClientAuth clientAuth, String[] protocols, boolean startTls, + String keyStore) + throws SSLException { + } +} + +@TargetClass(className = "io.netty.handler.ssl.JdkSslClientContext") +final class Target_io_netty_handler_ssl_JdkSslClientContext { + + @Alias + Target_io_netty_handler_ssl_JdkSslClientContext(Provider sslContextProvider, X509Certificate[] trustCertCollection, + TrustManagerFactory trustManagerFactory, X509Certificate[] keyCertChain, PrivateKey key, + String keyPassword, KeyManagerFactory keyManagerFactory, Iterable ciphers, + CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, String[] protocols, + long sessionCacheSize, long sessionTimeout, String keyStoreType) + throws SSLException { + + } +} + +@TargetClass(className = "io.netty.handler.ssl.SslHandler$SslEngineType") +final class Target_io_netty_handler_ssl_SslHandler$SslEngineType { + + @Alias + public static Target_io_netty_handler_ssl_SslHandler$SslEngineType JDK; + + @Substitute + static Target_io_netty_handler_ssl_SslHandler$SslEngineType forEngine(SSLEngine engine) { + return JDK; + } +} + +@TargetClass(className = "io.netty.handler.ssl.JdkAlpnApplicationProtocolNegotiator$AlpnWrapper") +final class Target_io_netty_handler_ssl_JdkAlpnApplicationProtocolNegotiator_AlpnWrapper { + @Substitute + public SSLEngine wrapSslEngine(SSLEngine engine, ByteBufAllocator alloc, + JdkApplicationProtocolNegotiator applicationNegotiator, boolean isServer) { + return (SSLEngine) (Object) new Target_io_netty_handler_ssl_JdkAlpnSslEngine(engine, applicationNegotiator, + isServer); + } + +} + +@TargetClass(className = "io.netty.handler.ssl.JdkAlpnSslEngine") +final class Target_io_netty_handler_ssl_JdkAlpnSslEngine { + @Alias + Target_io_netty_handler_ssl_JdkAlpnSslEngine(final SSLEngine engine, + final JdkApplicationProtocolNegotiator applicationNegotiator, final boolean isServer) { + + } +} + +@TargetClass(className = "io.netty.handler.ssl.SslContext") +final class Target_io_netty_handler_ssl_SslContext { + + @Substitute + static SslContext newServerContextInternal(SslProvider provider, Provider sslContextProvider, + X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory, + X509Certificate[] keyCertChain, + PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory, Iterable ciphers, + CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, long sessionCacheSize, long sessionTimeout, + ClientAuth clientAuth, String[] protocols, boolean startTls, boolean enableOcsp, String keyStoreType, + Map.Entry, Object>... ctxOptions) throws SSLException { + if (enableOcsp) { + throw new IllegalArgumentException("OCSP is not supported with this SslProvider: " + provider); + } + return (SslContext) (Object) new Target_io_netty_handler_ssl_JdkSslServerContext(sslContextProvider, + trustCertCollection, trustManagerFactory, keyCertChain, key, keyPassword, + keyManagerFactory, ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout, + clientAuth, protocols, startTls, keyStoreType); + } + + @Substitute + static SslContext newClientContextInternal(SslProvider provider, Provider sslContextProvider, + X509Certificate[] trustCert, + TrustManagerFactory trustManagerFactory, X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, + KeyManagerFactory keyManagerFactory, Iterable ciphers, CipherSuiteFilter cipherFilter, + ApplicationProtocolConfig apn, String[] protocols, long sessionCacheSize, long sessionTimeout, + boolean enableOcsp, + String keyStoreType, Map.Entry, Object>... options) throws SSLException { + if (enableOcsp) { + throw new IllegalArgumentException("OCSP is not supported with this SslProvider: " + provider); + } + return (SslContext) (Object) new Target_io_netty_handler_ssl_JdkSslClientContext(sslContextProvider, + trustCert, trustManagerFactory, keyCertChain, key, keyPassword, + keyManagerFactory, ciphers, cipherFilter, apn, protocols, sessionCacheSize, + sessionTimeout, keyStoreType); + } + +} + +@TargetClass(className = "io.netty.handler.ssl.JdkDefaultApplicationProtocolNegotiator") +final class Target_io_netty_handler_ssl_JdkDefaultApplicationProtocolNegotiator { + + @Alias + public static Target_io_netty_handler_ssl_JdkDefaultApplicationProtocolNegotiator INSTANCE; +} + +@TargetClass(className = "io.netty.handler.ssl.JdkSslContext") +final class Target_io_netty_handler_ssl_JdkSslContext { + + @Substitute + static JdkApplicationProtocolNegotiator toNegotiator(ApplicationProtocolConfig config, boolean isServer) { + if (config == null) { + return (JdkApplicationProtocolNegotiator) (Object) Target_io_netty_handler_ssl_JdkDefaultApplicationProtocolNegotiator.INSTANCE; + } + + switch (config.protocol()) { + case NONE: + return (JdkApplicationProtocolNegotiator) (Object) Target_io_netty_handler_ssl_JdkDefaultApplicationProtocolNegotiator.INSTANCE; + case ALPN: + if (isServer) { + // GRAAL RC9 bug: https://github.com/oracle/graal/issues/813 + // switch(config.selectorFailureBehavior()) { + // case FATAL_ALERT: + // return new JdkAlpnApplicationProtocolNegotiator(true, config.supportedProtocols()); + // case NO_ADVERTISE: + // return new JdkAlpnApplicationProtocolNegotiator(false, config.supportedProtocols()); + // default: + // throw new UnsupportedOperationException(new StringBuilder("JDK provider does not support ") + // .append(config.selectorFailureBehavior()).append(" failure behavior").toString()); + // } + SelectorFailureBehavior behavior = config.selectorFailureBehavior(); + if (behavior == SelectorFailureBehavior.FATAL_ALERT) { + return new JdkAlpnApplicationProtocolNegotiator(true, config.supportedProtocols()); + } else if (behavior == SelectorFailureBehavior.NO_ADVERTISE) { + return new JdkAlpnApplicationProtocolNegotiator(false, config.supportedProtocols()); + } else { + throw new UnsupportedOperationException(new StringBuilder("JDK provider does not support ") + .append(config.selectorFailureBehavior()).append(" failure behavior").toString()); + } + } else { + switch (config.selectedListenerFailureBehavior()) { + case ACCEPT: + return new JdkAlpnApplicationProtocolNegotiator(false, config.supportedProtocols()); + case FATAL_ALERT: + return new JdkAlpnApplicationProtocolNegotiator(true, config.supportedProtocols()); + default: + throw new UnsupportedOperationException(new StringBuilder("JDK provider does not support ") + .append(config.selectedListenerFailureBehavior()).append(" failure behavior") + .toString()); + } + } + default: + throw new UnsupportedOperationException( + new StringBuilder("JDK provider does not support ").append(config.protocol()) + .append(" protocol") + .toString()); + } + } + +} + +/* + * This one only prints exceptions otherwise we get a useless bogus + * exception message: https://github.com/eclipse-vertx/vert.x/issues/1657 + */ +@TargetClass(className = "io.netty.bootstrap.AbstractBootstrap") +final class Target_io_netty_bootstrap_AbstractBootstrap { + + @Alias + private ChannelFactory channelFactory; + + @Alias + void init(Channel channel) throws Exception { + } + + @Alias + public AbstractBootstrapConfig config() { + return null; + } + + @Substitute + final ChannelFuture initAndRegister() { + Channel channel = null; + try { + channel = channelFactory.newChannel(); + init(channel); + } catch (Throwable t) { + // THE FIX IS HERE: + t.printStackTrace(); + if (channel != null) { + // channel can be null if newChannel crashed (eg SocketException("too many open files")) + channel.unsafe().closeForcibly(); + } + // as the Channel is not registered yet, we need to force the usage of the GlobalEventExecutor + return new DefaultChannelPromise(channel, GlobalEventExecutor.INSTANCE).setFailure(t); + } + + ChannelFuture regFuture = config().group().register(channel); + if (regFuture.cause() != null) { + if (channel.isRegistered()) { + channel.close(); + } else { + channel.unsafe().closeForcibly(); + } + } + + // If we are here and the promise is not failed, it's one of the following cases: + // 1) If we attempted registration from the event loop, the registration has been completed at this point. + // i.e. It's safe to attempt bind() or connect() now because the channel has been registered. + // 2) If we attempted registration from the other thread, the registration request has been successfully + // added to the event loop's task queue for later execution. + // i.e. It's safe to attempt bind() or connect() now: + // because bind() or connect() will be executed *after* the scheduled registration task is executed + // because register(), bind(), and connect() are all bound to the same thread. + + return regFuture; + + } +} + +@TargetClass(className = "io.netty.channel.nio.NioEventLoop") +final class Target_io_netty_channel_nio_NioEventLoop { + + @Substitute + private static Queue newTaskQueue0(int maxPendingTasks) { + return new LinkedBlockingDeque<>(); + } +} + +@TargetClass(className = "io.netty.buffer.AbstractReferenceCountedByteBuf") +final class Target_io_netty_buffer_AbstractReferenceCountedByteBuf { + + @Alias + @RecomputeFieldValue(kind = Kind.FieldOffset, name = "refCnt") + private static long REFCNT_FIELD_OFFSET; +} + +@TargetClass(className = "io.netty.util.AbstractReferenceCounted") +final class Target_io_netty_util_AbstractReferenceCounted { + + @Alias + @RecomputeFieldValue(kind = Kind.FieldOffset, name = "refCnt") + private static long REFCNT_FIELD_OFFSET; +} + +// This class is runtime-initialized by NettyProcessor +final class Holder_io_netty_util_concurrent_ScheduledFutureTask { + static final long START_TIME = System.nanoTime(); +} + +@TargetClass(className = "io.netty.util.concurrent.AbstractScheduledEventExecutor") +final class Target_io_netty_util_concurrent_AbstractScheduledEventExecutor { + + // The START_TIME field is kept but not used. + // All the accesses to it have been replaced with Holder_io_netty_util_concurrent_ScheduledFutureTask + + @Substitute + static long initialNanoTime() { + return Holder_io_netty_util_concurrent_ScheduledFutureTask.START_TIME; + } + + @Substitute + static long defaultCurrentTimeNanos() { + return System.nanoTime() - Holder_io_netty_util_concurrent_ScheduledFutureTask.START_TIME; + } +} + +@TargetClass(className = "io.netty.channel.ChannelHandlerMask") +final class Target_io_netty_channel_ChannelHandlerMask { + + // Netty tries to self-optimized itself, but it requires lots of reflection. We disable this behavior and avoid + // misleading DEBUG messages in the log. + @Substitute + private static boolean isSkippable(final Class handlerType, final String methodName, final Class... paramTypes) { + return false; + } +} + +@TargetClass(className = "io.netty.util.internal.NativeLibraryLoader") +final class Target_io_netty_util_internal_NativeLibraryLoader { + + // This method can trick GraalVM into thinking that Classloader#defineClass is getting called + @Substitute + static Class tryToLoadClass(final ClassLoader loader, final Class helper) + throws ClassNotFoundException { + return Class.forName(helper.getName(), false, loader); + } + +} + +@TargetClass(className = "io.netty.buffer.EmptyByteBuf") +final class Target_io_netty_buffer_EmptyByteBuf { + + @Alias + @RecomputeFieldValue(kind = Kind.Reset) + private static ByteBuffer EMPTY_BYTE_BUFFER; + + @Alias + @RecomputeFieldValue(kind = Kind.Reset) + private static long EMPTY_BYTE_BUFFER_ADDRESS; + + @Substitute + public ByteBuffer nioBuffer() { + return EmptyByteBufStub.emptyByteBuffer(); + } + + @Substitute + public ByteBuffer[] nioBuffers() { + return new ByteBuffer[] { EmptyByteBufStub.emptyByteBuffer() }; + } + + @Substitute + public ByteBuffer internalNioBuffer(int index, int length) { + return EmptyByteBufStub.emptyByteBuffer(); + } + + @Substitute + public boolean hasMemoryAddress() { + return EmptyByteBufStub.emptyByteBufferAddress() != 0; + } + + @Substitute + public long memoryAddress() { + if (hasMemoryAddress()) { + return EmptyByteBufStub.emptyByteBufferAddress(); + } else { + throw new UnsupportedOperationException(); + } + } + +} + +@TargetClass(className = "io.netty.handler.codec.http.HttpContentDecompressor") +final class Target_io_netty_handler_codec_http_HttpContentDecompressor { + + @Alias + private boolean strict; + + @Alias + protected ChannelHandlerContext ctx; + + @Substitute + protected EmbeddedChannel newContentDecoder(String contentEncoding) throws Exception { + if (GZIP.contentEqualsIgnoreCase(contentEncoding) || + X_GZIP.contentEqualsIgnoreCase(contentEncoding)) { + return new EmbeddedChannel(ctx.channel().id(), ctx.channel().metadata().hasDisconnect(), + ctx.channel().config(), ZlibCodecFactory.newZlibDecoder(ZlibWrapper.GZIP)); + } + if (DEFLATE.contentEqualsIgnoreCase(contentEncoding) || + X_DEFLATE.contentEqualsIgnoreCase(contentEncoding)) { + final ZlibWrapper wrapper = strict ? ZlibWrapper.ZLIB : ZlibWrapper.ZLIB_OR_NONE; + // To be strict, 'deflate' means ZLIB, but some servers were not implemented correctly. + return new EmbeddedChannel(ctx.channel().id(), ctx.channel().metadata().hasDisconnect(), + ctx.channel().config(), ZlibCodecFactory.newZlibDecoder(wrapper)); + } + + // 'identity' or unsupported + return null; + } +} + +@TargetClass(className = "io.netty.handler.codec.http2.DelegatingDecompressorFrameListener") +final class Target_io_netty_handler_codec_http2_DelegatingDecompressorFrameListener { + + @Alias + boolean strict; + + @Substitute + protected EmbeddedChannel newContentDecompressor(ChannelHandlerContext ctx, CharSequence contentEncoding) + throws Http2Exception { + if (!HttpHeaderValues.GZIP.contentEqualsIgnoreCase(contentEncoding) + && !HttpHeaderValues.X_GZIP.contentEqualsIgnoreCase(contentEncoding)) { + if (!HttpHeaderValues.DEFLATE.contentEqualsIgnoreCase(contentEncoding) + && !HttpHeaderValues.X_DEFLATE.contentEqualsIgnoreCase(contentEncoding)) { + return null; + } else { + ZlibWrapper wrapper = this.strict ? ZlibWrapper.ZLIB : ZlibWrapper.ZLIB_OR_NONE; + return new EmbeddedChannel(ctx.channel().id(), ctx.channel().metadata().hasDisconnect(), ctx.channel().config(), + new ChannelHandler[] { ZlibCodecFactory.newZlibDecoder(wrapper) }); + } + } else { + return new EmbeddedChannel(ctx.channel().id(), ctx.channel().metadata().hasDisconnect(), ctx.channel().config(), + new ChannelHandler[] { ZlibCodecFactory.newZlibDecoder(ZlibWrapper.GZIP) }); + } + } +} + +@TargetClass(className = "io.netty.handler.ssl.SslHandler") +final class Target_SslHandler { + + @Substitute + private void setOpensslEngineSocketFd(Channel c) { + // do nothing. + } +} + +@TargetClass(className = "io.netty.handler.ssl.PemReader") +final class Alias_PemReader { + + @Alias + public static ByteBuf readPrivateKey(File keyFile) { + return null; + } + + @Alias + public static ByteBuf readPrivateKey(InputStream in) throws KeyException { + return null; + } +} + +/** + * If BouncyCastle is not on the classpath, we must not try to read the PEM file using the BouncyCatle PEM reader. + */ +@TargetClass(className = "io.netty.handler.ssl.SslContext", onlyWith = IsBouncyNotThere.class) +final class Target_SslContext { + + @Substitute + protected static PrivateKey toPrivateKey(File keyFile, String keyPassword) throws NoSuchAlgorithmException, + NoSuchPaddingException, InvalidKeySpecException, + InvalidAlgorithmParameterException, + KeyException, IOException { + if (keyFile == null) { + return null; + } + + return getPrivateKeyFromByteBuffer(Alias_PemReader.readPrivateKey(keyFile), keyPassword); + } + + @Substitute + protected static PrivateKey toPrivateKey(InputStream keyInputStream, String keyPassword) + throws NoSuchAlgorithmException, + NoSuchPaddingException, InvalidKeySpecException, + InvalidAlgorithmParameterException, + KeyException, IOException { + if (keyInputStream == null) { + return null; + } + + return getPrivateKeyFromByteBuffer(Alias_PemReader.readPrivateKey(keyInputStream), keyPassword); + } + + @Alias + private static PrivateKey getPrivateKeyFromByteBuffer(ByteBuf encodedKeyBuf, String keyPassword) + throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeySpecException, + InvalidAlgorithmParameterException, KeyException, IOException { + return null; + } +} + +class IsBouncyNotThere implements BooleanSupplier { + + @Override + public boolean getAsBoolean() { + try { + NettySubstitutions.class.getClassLoader().loadClass("org.bouncycastle.openssl.PEMParser"); + return false; + } catch (Exception e) { + return true; + } + } +} + +class NettySubstitutions { + +} diff --git a/driver/src/test/java/graal/VertxSubstitutions.java b/driver/src/test/java/graal/VertxSubstitutions.java new file mode 100644 index 000000000..2127e16f0 --- /dev/null +++ b/driver/src/test/java/graal/VertxSubstitutions.java @@ -0,0 +1,195 @@ +package graal; + +import com.oracle.svm.core.annotate.Alias; +import com.oracle.svm.core.annotate.Substitute; +import com.oracle.svm.core.annotate.TargetClass; +import io.netty.handler.ssl.*; +import io.vertx.core.MultiMap; +import io.vertx.core.Promise; +import io.vertx.core.Vertx; +import io.vertx.core.dns.AddressResolverOptions; +import io.vertx.core.eventbus.EventBusOptions; +import io.vertx.core.eventbus.impl.HandlerHolder; +import io.vertx.core.eventbus.impl.HandlerRegistration; +import io.vertx.core.eventbus.impl.MessageImpl; +import io.vertx.core.eventbus.impl.OutboundDeliveryContext; +import io.vertx.core.impl.ContextInternal; +import io.vertx.core.impl.VertxInternal; +import io.vertx.core.impl.resolver.DefaultResolverProvider; +import io.vertx.core.net.NetServerOptions; +import io.vertx.core.net.impl.transport.Transport; +import io.vertx.core.spi.resolver.ResolverProvider; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLException; +import javax.net.ssl.TrustManagerFactory; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.concurrent.ConcurrentMap; + +@TargetClass(className = "io.vertx.core.net.impl.transport.Transport") +final class Target_io_vertx_core_net_impl_transport_Transport { + @Substitute + public static Transport nativeTransport() { + return Transport.JDK; + } +} + +/** + * This substitution forces the usage of the blocking DNS resolver + */ +@TargetClass(className = "io.vertx.core.spi.resolver.ResolverProvider") +final class TargetResolverProvider { + + @Substitute + public static ResolverProvider factory(Vertx vertx, AddressResolverOptions options) { + return new DefaultResolverProvider(); + } +} + +@TargetClass(className = "io.vertx.core.net.OpenSSLEngineOptions") +final class Target_io_vertx_core_net_OpenSSLEngineOptions { + + @Substitute + public static boolean isAvailable() { + return false; + } + + @Substitute + public static boolean isAlpnAvailable() { + return false; + } +} + +@SuppressWarnings("rawtypes") +@TargetClass(className = "io.vertx.core.eventbus.impl.clustered.ClusteredEventBus") +final class Target_io_vertx_core_eventbus_impl_clustered_ClusteredEventBusClusteredEventBus { + + @Substitute + private NetServerOptions getServerOptions() { + throw new RuntimeException("Not Implemented"); + } + + @Substitute + public void start(Promise promise) { + throw new RuntimeException("Not Implemented"); + } + + @Substitute + public void close(Promise promise) { + throw new RuntimeException("Not Implemented"); + } + + @Substitute + public MessageImpl createMessage(boolean send, String address, MultiMap headers, Object body, String codecName) { + throw new RuntimeException("Not Implemented"); + } + + @Substitute + protected void onLocalRegistration(HandlerHolder handlerHolder, Promise promise) { + throw new RuntimeException("Not Implemented"); + } + + @Substitute + protected HandlerHolder createHandlerHolder(HandlerRegistration registration, boolean replyHandler, + boolean localOnly, ContextInternal context) { + throw new RuntimeException("Not Implemented"); + } + + @Substitute + protected void onLocalUnregistration(HandlerHolder handlerHolder, Promise completionHandler) { + throw new RuntimeException("Not Implemented"); + } + + @Substitute + protected void sendOrPub(OutboundDeliveryContext sendContext) { + throw new RuntimeException("Not Implemented"); + } + + @Substitute + protected String generateReplyAddress() { + throw new RuntimeException("Not Implemented"); + } + + @Substitute + protected boolean isMessageLocal(MessageImpl msg) { + throw new RuntimeException("Not Implemented"); + } + + @Substitute + ConcurrentMap connections() { + throw new RuntimeException("Not Implemented"); + } + + @Substitute + VertxInternal vertx() { + throw new RuntimeException("Not Implemented"); + } + + @Substitute + EventBusOptions options() { + throw new RuntimeException("Not Implemented"); + } +} + +@TargetClass(className = "io.vertx.core.spi.tls.DefaultSslContextFactory") +final class Target_DefaultSslContextFactory { + + @Alias + private Set enabledCipherSuites; + + @Alias + private List applicationProtocols; + + @Alias + private ClientAuth clientAuth; + + @Substitute + private SslContext createContext(boolean useAlpn, boolean client, KeyManagerFactory kmf, TrustManagerFactory tmf) + throws SSLException { + SslContextBuilder builder; + if (client) { + builder = SslContextBuilder.forClient(); + if (kmf != null) { + builder.keyManager(kmf); + } + } else { + builder = SslContextBuilder.forServer(kmf); + } + Collection cipherSuites = enabledCipherSuites; + builder.sslProvider(SslProvider.JDK); + if (cipherSuites == null || cipherSuites.isEmpty()) { + cipherSuites = Target_io_vertx_core_spi_tls_DefaultJDKCipherSuite.get(); + } + if (tmf != null) { + builder.trustManager(tmf); + } + if (cipherSuites != null && cipherSuites.size() > 0) { + builder.ciphers(cipherSuites); + } + if (useAlpn && applicationProtocols != null && applicationProtocols.size() > 0) { + builder.applicationProtocolConfig(new ApplicationProtocolConfig( + ApplicationProtocolConfig.Protocol.ALPN, + ApplicationProtocolConfig.SelectorFailureBehavior.NO_ADVERTISE, + ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT, + applicationProtocols)); + } + if (clientAuth != null) { + builder.clientAuth(clientAuth); + } + return builder.build(); + } +} + +@TargetClass(className = "io.vertx.core.spi.tls.DefaultJDKCipherSuite") +final class Target_io_vertx_core_spi_tls_DefaultJDKCipherSuite { + @Alias + static List get() { + return null; + } +} + +class VertxSubstitutions { + +} diff --git a/driver/src/test/java/graal/ZLibSubstitutions.java b/driver/src/test/java/graal/ZLibSubstitutions.java new file mode 100644 index 000000000..515cf51e9 --- /dev/null +++ b/driver/src/test/java/graal/ZLibSubstitutions.java @@ -0,0 +1,66 @@ +package graal; + +import com.oracle.svm.core.annotate.Substitute; +import com.oracle.svm.core.annotate.TargetClass; +import io.netty.handler.codec.compression.*; + +/** + * This substitution avoid having jcraft zlib added to the build + */ +@TargetClass(className = "io.netty.handler.codec.compression.ZlibCodecFactory") +final class Target_io_netty_handler_codec_compression_ZlibCodecFactory { + + @Substitute + public static ZlibEncoder newZlibEncoder(int compressionLevel) { + return new JdkZlibEncoder(compressionLevel); + } + + @Substitute + public static ZlibEncoder newZlibEncoder(ZlibWrapper wrapper) { + return new JdkZlibEncoder(wrapper); + } + + @Substitute + public static ZlibEncoder newZlibEncoder(ZlibWrapper wrapper, int compressionLevel) { + return new JdkZlibEncoder(wrapper, compressionLevel); + } + + @Substitute + public static ZlibEncoder newZlibEncoder(ZlibWrapper wrapper, int compressionLevel, int windowBits, int memLevel) { + return new JdkZlibEncoder(wrapper, compressionLevel); + } + + @Substitute + public static ZlibEncoder newZlibEncoder(byte[] dictionary) { + return new JdkZlibEncoder(dictionary); + } + + @Substitute + public static ZlibEncoder newZlibEncoder(int compressionLevel, byte[] dictionary) { + return new JdkZlibEncoder(compressionLevel, dictionary); + } + + @Substitute + public static ZlibEncoder newZlibEncoder(int compressionLevel, int windowBits, int memLevel, byte[] dictionary) { + return new JdkZlibEncoder(compressionLevel, dictionary); + } + + @Substitute + public static ZlibDecoder newZlibDecoder() { + return new JdkZlibDecoder(); + } + + @Substitute + public static ZlibDecoder newZlibDecoder(ZlibWrapper wrapper) { + return new JdkZlibDecoder(wrapper); + } + + @Substitute + public static ZlibDecoder newZlibDecoder(byte[] dictionary) { + return new JdkZlibDecoder(dictionary); + } +} + +class ZLibSubstitutions { + +} diff --git a/driver/src/test/java/graalvm/UnicodeUtilsTest.java b/driver/src/test/java/unicode/UnicodeUtilsTest.java similarity index 100% rename from driver/src/test/java/graalvm/UnicodeUtilsTest.java rename to driver/src/test/java/unicode/UnicodeUtilsTest.java diff --git a/driver/src/test/resources/META-INF/native-image/native-image.properties b/driver/src/test/resources/META-INF/native-image/native-image.properties index 2aa13d2f3..7a9968e8f 100644 --- a/driver/src/test/resources/META-INF/native-image/native-image.properties +++ b/driver/src/test/resources/META-INF/native-image/native-image.properties @@ -3,5 +3,4 @@ Args=\ -H:ReflectionConfigurationResources=${.}/reflect-config.json \ -H:SerializationConfigurationResources=${.}/serialization-config.json \ --initialize-at-build-time=\ - ch.qos.logback,\ org.junit.platform.engine.TestTag diff --git a/driver/src/test/resources/META-INF/native-image/reflect-config.json b/driver/src/test/resources/META-INF/native-image/reflect-config.json index e8a1f86bc..904da3577 100644 --- a/driver/src/test/resources/META-INF/native-image/reflect-config.json +++ b/driver/src/test/resources/META-INF/native-image/reflect-config.json @@ -12,80 +12,6 @@ } ] }, - { - "name": "ch.qos.logback.classic.encoder.PatternLayoutEncoder", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "ch.qos.logback.classic.pattern.DateConverter", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "ch.qos.logback.classic.pattern.LevelConverter", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "ch.qos.logback.classic.pattern.LineSeparatorConverter", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "ch.qos.logback.classic.pattern.LoggerConverter", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "ch.qos.logback.classic.pattern.MessageConverter", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "ch.qos.logback.classic.pattern.ThreadConverter", - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, - { - "name": "ch.qos.logback.core.ConsoleAppender", - "allPublicMethods": true, - "methods": [ - { - "name": "", - "parameterTypes": [] - } - ] - }, { "name": "com.arangodb.ArangoCollectionTest$TestUpdateEntity", "allDeclaredFields":true, diff --git a/driver/src/test/resources/logback-test.xml b/driver/src/test/resources/logback-test.xml deleted file mode 100644 index b1d65b196..000000000 --- a/driver/src/test/resources/logback-test.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - - - - - diff --git a/driver/src/test/resources/simplelogger.properties b/driver/src/test/resources/simplelogger.properties new file mode 100644 index 000000000..250d7c6b1 --- /dev/null +++ b/driver/src/test/resources/simplelogger.properties @@ -0,0 +1,10 @@ +org.slf4j.simpleLogger.logFile=System.out +org.slf4j.simpleLogger.showDateTime=true +org.slf4j.simpleLogger.dateTimeFormat=HH:mm:ss.SSS +org.slf4j.simpleLogger.showThreadName=true +org.slf4j.simpleLogger.showLogName=true +org.slf4j.simpleLogger.showShortLogName=false + + +org.slf4j.simpleLogger.defaultLogLevel=info +#org.slf4j.simpleLogger.log.com.arangodb.http.HttpCommunication=debug diff --git a/pom.xml b/pom.xml index 22ce8fb6b..1cf00c101 100644 --- a/pom.xml +++ b/pom.xml @@ -61,8 +61,8 @@ - ch.qos.logback - logback-classic + org.slf4j + slf4j-simple test @@ -161,12 +161,12 @@ org.slf4j slf4j-api - 2.0.5 + 2.0.6 - ch.qos.logback - logback-classic - 1.3.5 + org.slf4j + slf4j-simple + 2.0.6 org.assertj @@ -429,6 +429,7 @@ false --no-fallback + --link-at-build-time ${SslTest} @@ -437,6 +438,20 @@ + + + com.aayushatharva.brotli4j + brotli4j + 1.11.0 + test + + + javax.annotation + javax.annotation-api + 1.3.2 + test + + diff --git a/resilience-tests/pom.xml b/resilience-tests/pom.xml index 8d379f9bf..53371a117 100644 --- a/resilience-tests/pom.xml +++ b/resilience-tests/pom.xml @@ -35,6 +35,11 @@ awaitility 4.2.0 + + ch.qos.logback + logback-classic + 1.3.5 + \ No newline at end of file From 48b6673fd91e9288bdd4602a0007000b077b2f87 Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Fri, 3 Mar 2023 20:37:31 +0100 Subject: [PATCH 07/12] shaded native tests with --link-at-build-time --- shaded/pom.xml | 6 + .../main/java/graal/BrotliSubstitutions.java | 22 + .../src/main/java/graal/EmptyByteBufStub.java | 33 + .../HttpContentCompressorSubstitutions.java | 29 + .../main/java/graal/NettySubstitutions.java | 605 ++++++++++++++++++ .../main/java/graal/VertxSubstitutions.java | 195 ++++++ .../main/java/graal/ZLibSubstitutions.java | 66 ++ .../native-image.properties | 40 +- ...-config.json => reflect-config-netty.json} | 0 9 files changed, 990 insertions(+), 6 deletions(-) create mode 100644 shaded/src/main/java/graal/BrotliSubstitutions.java create mode 100644 shaded/src/main/java/graal/EmptyByteBufStub.java create mode 100644 shaded/src/main/java/graal/HttpContentCompressorSubstitutions.java create mode 100644 shaded/src/main/java/graal/NettySubstitutions.java create mode 100644 shaded/src/main/java/graal/VertxSubstitutions.java create mode 100644 shaded/src/main/java/graal/ZLibSubstitutions.java rename shaded/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver-shaded/{netty-reflect-config.json => reflect-config-netty.json} (100%) diff --git a/shaded/pom.xml b/shaded/pom.xml index a0ec6429f..a04e5f863 100644 --- a/shaded/pom.xml +++ b/shaded/pom.xml @@ -40,6 +40,12 @@ org.slf4j slf4j-api + + org.graalvm.sdk + graal-sdk + 22.3.1 + provided + diff --git a/shaded/src/main/java/graal/BrotliSubstitutions.java b/shaded/src/main/java/graal/BrotliSubstitutions.java new file mode 100644 index 000000000..fee8b14a1 --- /dev/null +++ b/shaded/src/main/java/graal/BrotliSubstitutions.java @@ -0,0 +1,22 @@ +package graal; + +import com.oracle.svm.core.annotate.Substitute; +import com.oracle.svm.core.annotate.TargetClass; + + +@TargetClass(className = "io.netty.handler.codec.compression.Brotli") +final class Target_com_arangodb_shaded_netty_handler_codec_compression_Brotli { + @Substitute + public static boolean isAvailable() { + return false; + } + + @Substitute + public static void ensureAvailability() throws Throwable { + throw new UnsupportedOperationException(); + } +} + +public class BrotliSubstitutions { + +} diff --git a/shaded/src/main/java/graal/EmptyByteBufStub.java b/shaded/src/main/java/graal/EmptyByteBufStub.java new file mode 100644 index 000000000..2f46d7c5c --- /dev/null +++ b/shaded/src/main/java/graal/EmptyByteBufStub.java @@ -0,0 +1,33 @@ +package graal; + +import io.netty.util.internal.PlatformDependent; + +import java.nio.ByteBuffer; + +public final class EmptyByteBufStub { + private static final ByteBuffer EMPTY_BYTE_BUFFER = ByteBuffer.allocateDirect(0); + private static final long EMPTY_BYTE_BUFFER_ADDRESS; + + static { + long emptyByteBufferAddress = 0; + try { + if (PlatformDependent.hasUnsafe()) { + emptyByteBufferAddress = PlatformDependent.directBufferAddress(EMPTY_BYTE_BUFFER); + } + } catch (Throwable t) { + // Ignore + } + EMPTY_BYTE_BUFFER_ADDRESS = emptyByteBufferAddress; + } + + public static ByteBuffer emptyByteBuffer() { + return EMPTY_BYTE_BUFFER; + } + + public static long emptyByteBufferAddress() { + return EMPTY_BYTE_BUFFER_ADDRESS; + } + + private EmptyByteBufStub() { + } +} diff --git a/shaded/src/main/java/graal/HttpContentCompressorSubstitutions.java b/shaded/src/main/java/graal/HttpContentCompressorSubstitutions.java new file mode 100644 index 000000000..92bed76be --- /dev/null +++ b/shaded/src/main/java/graal/HttpContentCompressorSubstitutions.java @@ -0,0 +1,29 @@ +package graal; + +import com.oracle.svm.core.annotate.Substitute; +import com.oracle.svm.core.annotate.TargetClass; +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelHandlerContext; + +public class HttpContentCompressorSubstitutions { + + @TargetClass(className = "io.netty.handler.codec.compression.ZstdEncoder") + public static final class ZstdEncoderFactorySubstitution { + + @Substitute + protected ByteBuf allocateBuffer(ChannelHandlerContext ctx, ByteBuf msg, boolean preferDirect) throws Exception { + throw new UnsupportedOperationException(); + } + + @Substitute + protected void encode(ChannelHandlerContext ctx, ByteBuf in, ByteBuf out) { + throw new UnsupportedOperationException(); + } + + @Substitute + public void flush(final ChannelHandlerContext ctx) { + throw new UnsupportedOperationException(); + } + } + +} diff --git a/shaded/src/main/java/graal/NettySubstitutions.java b/shaded/src/main/java/graal/NettySubstitutions.java new file mode 100644 index 000000000..856420318 --- /dev/null +++ b/shaded/src/main/java/graal/NettySubstitutions.java @@ -0,0 +1,605 @@ +package graal; + +import com.oracle.svm.core.annotate.Alias; +import com.oracle.svm.core.annotate.RecomputeFieldValue; +import com.oracle.svm.core.annotate.RecomputeFieldValue.Kind; +import com.oracle.svm.core.annotate.Substitute; +import com.oracle.svm.core.annotate.TargetClass; +import io.netty.bootstrap.AbstractBootstrapConfig; +import io.netty.bootstrap.ChannelFactory; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufAllocator; +import io.netty.channel.*; +import io.netty.channel.embedded.EmbeddedChannel; +import io.netty.handler.codec.compression.ZlibCodecFactory; +import io.netty.handler.codec.compression.ZlibWrapper; +import io.netty.handler.codec.http.HttpHeaderValues; +import io.netty.handler.codec.http2.Http2Exception; +import io.netty.handler.ssl.*; +import io.netty.handler.ssl.ApplicationProtocolConfig.SelectorFailureBehavior; +import io.netty.util.concurrent.GlobalEventExecutor; +import io.netty.util.internal.logging.InternalLoggerFactory; +import io.netty.util.internal.logging.JdkLoggerFactory; + +import javax.crypto.NoSuchPaddingException; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLException; +import javax.net.ssl.TrustManagerFactory; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; +import java.security.*; +import java.security.cert.X509Certificate; +import java.security.spec.InvalidKeySpecException; +import java.util.*; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.function.BooleanSupplier; + +import static io.netty.handler.codec.http.HttpHeaderValues.*; + +/** + * This substitution avoid having loggers added to the build + */ +@TargetClass(className = "io.netty.util.internal.logging.InternalLoggerFactory") +final class Target_com_arangodb_shaded_netty_util_internal_logging_InternalLoggerFactory { + + @Substitute + private static InternalLoggerFactory newDefaultFactory(String name) { + return JdkLoggerFactory.INSTANCE; + } +} + +// SSL +// This whole section is mostly about removing static analysis references to openssl/tcnative + +@TargetClass(className = "io.netty.handler.ssl.SslProvider") +final class Target_com_arangodb_shaded_netty_handler_ssl_SslProvider { + @Substitute + public static boolean isAlpnSupported(final SslProvider provider) { + switch (provider) { + case JDK: + return Target_com_arangodb_shaded_netty_handler_ssl_JdkAlpnApplicationProtocolNegotiator.isAlpnSupported(); + case OPENSSL: + case OPENSSL_REFCNT: + return false; + default: + throw new Error("SslProvider unsupported: " + provider); + } + } +} + +@TargetClass(className = "io.netty.handler.ssl.JdkAlpnApplicationProtocolNegotiator") +final class Target_com_arangodb_shaded_netty_handler_ssl_JdkAlpnApplicationProtocolNegotiator { + @Alias + static boolean isAlpnSupported() { + return true; + } +} + +/** + * Hardcode io.netty.handler.ssl.OpenSsl as non-available + */ +@TargetClass(className = "io.netty.handler.ssl.OpenSsl") +final class Target_com_arangodb_shaded_netty_handler_ssl_OpenSsl { + + @Alias + @RecomputeFieldValue(kind = Kind.FromAlias) + private static Throwable UNAVAILABILITY_CAUSE = new RuntimeException("OpenSsl unsupported!"); + + @Alias + @RecomputeFieldValue(kind = Kind.FromAlias) + static List DEFAULT_CIPHERS = Collections.emptyList(); + + @Alias + @RecomputeFieldValue(kind = Kind.FromAlias) + static Set AVAILABLE_CIPHER_SUITES = Collections.emptySet(); + + @Alias + @RecomputeFieldValue(kind = Kind.FromAlias) + private static Set AVAILABLE_OPENSSL_CIPHER_SUITES = Collections.emptySet(); + + @Alias + @RecomputeFieldValue(kind = Kind.FromAlias) + private static Set AVAILABLE_JAVA_CIPHER_SUITES = Collections.emptySet(); + + @Alias + @RecomputeFieldValue(kind = Kind.FromAlias) + private static boolean SUPPORTS_KEYMANAGER_FACTORY = false; + + @Alias + @RecomputeFieldValue(kind = Kind.FromAlias) + private static boolean SUPPORTS_OCSP = false; + + @Alias + @RecomputeFieldValue(kind = Kind.FromAlias) + static Set SUPPORTED_PROTOCOLS_SET = Collections.emptySet(); + + @Substitute + public static boolean isAvailable() { + return false; + } + + @Substitute + public static int version() { + return -1; + } + + @Substitute + public static String versionString() { + return null; + } + + @Substitute + public static boolean isCipherSuiteAvailable(String cipherSuite) { + return false; + } +} + +@TargetClass(className = "io.netty.handler.ssl.JdkSslServerContext") +final class Target_com_arangodb_shaded_netty_handler_ssl_JdkSslServerContext { + + @Alias + Target_com_arangodb_shaded_netty_handler_ssl_JdkSslServerContext(Provider provider, + X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory, + X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, + KeyManagerFactory keyManagerFactory, Iterable ciphers, CipherSuiteFilter cipherFilter, + ApplicationProtocolConfig apn, long sessionCacheSize, long sessionTimeout, + ClientAuth clientAuth, String[] protocols, boolean startTls, + String keyStore) + throws SSLException { + } +} + +@TargetClass(className = "io.netty.handler.ssl.JdkSslClientContext") +final class Target_com_arangodb_shaded_netty_handler_ssl_JdkSslClientContext { + + @Alias + Target_com_arangodb_shaded_netty_handler_ssl_JdkSslClientContext(Provider sslContextProvider, X509Certificate[] trustCertCollection, + TrustManagerFactory trustManagerFactory, X509Certificate[] keyCertChain, PrivateKey key, + String keyPassword, KeyManagerFactory keyManagerFactory, Iterable ciphers, + CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, String[] protocols, + long sessionCacheSize, long sessionTimeout, String keyStoreType) + throws SSLException { + + } +} + +@TargetClass(className = "io.netty.handler.ssl.SslHandler$SslEngineType") +final class Target_com_arangodb_shaded_netty_handler_ssl_SslHandler$SslEngineType { + + @Alias + public static Target_com_arangodb_shaded_netty_handler_ssl_SslHandler$SslEngineType JDK; + + @Substitute + static Target_com_arangodb_shaded_netty_handler_ssl_SslHandler$SslEngineType forEngine(SSLEngine engine) { + return JDK; + } +} + +@TargetClass(className = "io.netty.handler.ssl.JdkAlpnApplicationProtocolNegotiator$AlpnWrapper") +final class Target_com_arangodb_shaded_netty_handler_ssl_JdkAlpnApplicationProtocolNegotiator_AlpnWrapper { + @Substitute + public SSLEngine wrapSslEngine(SSLEngine engine, ByteBufAllocator alloc, + JdkApplicationProtocolNegotiator applicationNegotiator, boolean isServer) { + return (SSLEngine) (Object) new Target_com_arangodb_shaded_netty_handler_ssl_JdkAlpnSslEngine(engine, applicationNegotiator, + isServer); + } + +} + +@TargetClass(className = "io.netty.handler.ssl.JdkAlpnSslEngine") +final class Target_com_arangodb_shaded_netty_handler_ssl_JdkAlpnSslEngine { + @Alias + Target_com_arangodb_shaded_netty_handler_ssl_JdkAlpnSslEngine(final SSLEngine engine, + final JdkApplicationProtocolNegotiator applicationNegotiator, final boolean isServer) { + + } +} + +@TargetClass(className = "io.netty.handler.ssl.SslContext") +final class Target_com_arangodb_shaded_netty_handler_ssl_SslContext { + + @Substitute + static SslContext newServerContextInternal(SslProvider provider, Provider sslContextProvider, + X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory, + X509Certificate[] keyCertChain, + PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory, Iterable ciphers, + CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn, long sessionCacheSize, long sessionTimeout, + ClientAuth clientAuth, String[] protocols, boolean startTls, boolean enableOcsp, String keyStoreType, + Map.Entry, Object>... ctxOptions) throws SSLException { + if (enableOcsp) { + throw new IllegalArgumentException("OCSP is not supported with this SslProvider: " + provider); + } + return (SslContext) (Object) new Target_com_arangodb_shaded_netty_handler_ssl_JdkSslServerContext(sslContextProvider, + trustCertCollection, trustManagerFactory, keyCertChain, key, keyPassword, + keyManagerFactory, ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout, + clientAuth, protocols, startTls, keyStoreType); + } + + @Substitute + static SslContext newClientContextInternal(SslProvider provider, Provider sslContextProvider, + X509Certificate[] trustCert, + TrustManagerFactory trustManagerFactory, X509Certificate[] keyCertChain, PrivateKey key, String keyPassword, + KeyManagerFactory keyManagerFactory, Iterable ciphers, CipherSuiteFilter cipherFilter, + ApplicationProtocolConfig apn, String[] protocols, long sessionCacheSize, long sessionTimeout, + boolean enableOcsp, + String keyStoreType, Map.Entry, Object>... options) throws SSLException { + if (enableOcsp) { + throw new IllegalArgumentException("OCSP is not supported with this SslProvider: " + provider); + } + return (SslContext) (Object) new Target_com_arangodb_shaded_netty_handler_ssl_JdkSslClientContext(sslContextProvider, + trustCert, trustManagerFactory, keyCertChain, key, keyPassword, + keyManagerFactory, ciphers, cipherFilter, apn, protocols, sessionCacheSize, + sessionTimeout, keyStoreType); + } + +} + +@TargetClass(className = "io.netty.handler.ssl.JdkDefaultApplicationProtocolNegotiator") +final class Target_com_arangodb_shaded_netty_handler_ssl_JdkDefaultApplicationProtocolNegotiator { + + @Alias + public static Target_com_arangodb_shaded_netty_handler_ssl_JdkDefaultApplicationProtocolNegotiator INSTANCE; +} + +@TargetClass(className = "io.netty.handler.ssl.JdkSslContext") +final class Target_com_arangodb_shaded_netty_handler_ssl_JdkSslContext { + + @Substitute + static JdkApplicationProtocolNegotiator toNegotiator(ApplicationProtocolConfig config, boolean isServer) { + if (config == null) { + return (JdkApplicationProtocolNegotiator) (Object) Target_com_arangodb_shaded_netty_handler_ssl_JdkDefaultApplicationProtocolNegotiator.INSTANCE; + } + + switch (config.protocol()) { + case NONE: + return (JdkApplicationProtocolNegotiator) (Object) Target_com_arangodb_shaded_netty_handler_ssl_JdkDefaultApplicationProtocolNegotiator.INSTANCE; + case ALPN: + if (isServer) { + // GRAAL RC9 bug: https://github.com/oracle/graal/issues/813 + // switch(config.selectorFailureBehavior()) { + // case FATAL_ALERT: + // return new JdkAlpnApplicationProtocolNegotiator(true, config.supportedProtocols()); + // case NO_ADVERTISE: + // return new JdkAlpnApplicationProtocolNegotiator(false, config.supportedProtocols()); + // default: + // throw new UnsupportedOperationException(new StringBuilder("JDK provider does not support ") + // .append(config.selectorFailureBehavior()).append(" failure behavior").toString()); + // } + SelectorFailureBehavior behavior = config.selectorFailureBehavior(); + if (behavior == SelectorFailureBehavior.FATAL_ALERT) { + return new JdkAlpnApplicationProtocolNegotiator(true, config.supportedProtocols()); + } else if (behavior == SelectorFailureBehavior.NO_ADVERTISE) { + return new JdkAlpnApplicationProtocolNegotiator(false, config.supportedProtocols()); + } else { + throw new UnsupportedOperationException(new StringBuilder("JDK provider does not support ") + .append(config.selectorFailureBehavior()).append(" failure behavior").toString()); + } + } else { + switch (config.selectedListenerFailureBehavior()) { + case ACCEPT: + return new JdkAlpnApplicationProtocolNegotiator(false, config.supportedProtocols()); + case FATAL_ALERT: + return new JdkAlpnApplicationProtocolNegotiator(true, config.supportedProtocols()); + default: + throw new UnsupportedOperationException(new StringBuilder("JDK provider does not support ") + .append(config.selectedListenerFailureBehavior()).append(" failure behavior") + .toString()); + } + } + default: + throw new UnsupportedOperationException( + new StringBuilder("JDK provider does not support ").append(config.protocol()) + .append(" protocol") + .toString()); + } + } + +} + +/* + * This one only prints exceptions otherwise we get a useless bogus + * exception message: https://github.com/eclipse-vertx/vert.x/issues/1657 + */ +@TargetClass(className = "io.netty.bootstrap.AbstractBootstrap") +final class Target_com_arangodb_shaded_netty_bootstrap_AbstractBootstrap { + + @Alias + private ChannelFactory channelFactory; + + @Alias + void init(Channel channel) throws Exception { + } + + @Alias + public AbstractBootstrapConfig config() { + return null; + } + + @Substitute + final ChannelFuture initAndRegister() { + Channel channel = null; + try { + channel = channelFactory.newChannel(); + init(channel); + } catch (Throwable t) { + // THE FIX IS HERE: + t.printStackTrace(); + if (channel != null) { + // channel can be null if newChannel crashed (eg SocketException("too many open files")) + channel.unsafe().closeForcibly(); + } + // as the Channel is not registered yet, we need to force the usage of the GlobalEventExecutor + return new DefaultChannelPromise(channel, GlobalEventExecutor.INSTANCE).setFailure(t); + } + + ChannelFuture regFuture = config().group().register(channel); + if (regFuture.cause() != null) { + if (channel.isRegistered()) { + channel.close(); + } else { + channel.unsafe().closeForcibly(); + } + } + + // If we are here and the promise is not failed, it's one of the following cases: + // 1) If we attempted registration from the event loop, the registration has been completed at this point. + // i.e. It's safe to attempt bind() or connect() now because the channel has been registered. + // 2) If we attempted registration from the other thread, the registration request has been successfully + // added to the event loop's task queue for later execution. + // i.e. It's safe to attempt bind() or connect() now: + // because bind() or connect() will be executed *after* the scheduled registration task is executed + // because register(), bind(), and connect() are all bound to the same thread. + + return regFuture; + + } +} + +@TargetClass(className = "io.netty.channel.nio.NioEventLoop") +final class Target_com_arangodb_shaded_netty_channel_nio_NioEventLoop { + + @Substitute + private static Queue newTaskQueue0(int maxPendingTasks) { + return new LinkedBlockingDeque<>(); + } +} + +@TargetClass(className = "io.netty.buffer.AbstractReferenceCountedByteBuf") +final class Target_com_arangodb_shaded_netty_buffer_AbstractReferenceCountedByteBuf { + + @Alias + @RecomputeFieldValue(kind = Kind.FieldOffset, name = "refCnt") + private static long REFCNT_FIELD_OFFSET; +} + +@TargetClass(className = "io.netty.util.AbstractReferenceCounted") +final class Target_com_arangodb_shaded_netty_util_AbstractReferenceCounted { + + @Alias + @RecomputeFieldValue(kind = Kind.FieldOffset, name = "refCnt") + private static long REFCNT_FIELD_OFFSET; +} + +// This class is runtime-initialized by NettyProcessor +final class Holder_com_arangodb_shaded_netty_util_concurrent_ScheduledFutureTask { + static final long START_TIME = System.nanoTime(); +} + +@TargetClass(className = "io.netty.util.concurrent.AbstractScheduledEventExecutor") +final class Target_com_arangodb_shaded_netty_util_concurrent_AbstractScheduledEventExecutor { + + // The START_TIME field is kept but not used. + // All the accesses to it have been replaced with Holder_com_arangodb_shaded_netty_util_concurrent_ScheduledFutureTask + + @Substitute + static long initialNanoTime() { + return Holder_com_arangodb_shaded_netty_util_concurrent_ScheduledFutureTask.START_TIME; + } + + @Substitute + static long defaultCurrentTimeNanos() { + return System.nanoTime() - Holder_com_arangodb_shaded_netty_util_concurrent_ScheduledFutureTask.START_TIME; + } +} + +@TargetClass(className = "io.netty.channel.ChannelHandlerMask") +final class Target_com_arangodb_shaded_netty_channel_ChannelHandlerMask { + + // Netty tries to self-optimized itself, but it requires lots of reflection. We disable this behavior and avoid + // misleading DEBUG messages in the log. + @Substitute + private static boolean isSkippable(final Class handlerType, final String methodName, final Class... paramTypes) { + return false; + } +} + +@TargetClass(className = "io.netty.util.internal.NativeLibraryLoader") +final class Target_com_arangodb_shaded_netty_util_internal_NativeLibraryLoader { + + // This method can trick GraalVM into thinking that Classloader#defineClass is getting called + @Substitute + static Class tryToLoadClass(final ClassLoader loader, final Class helper) + throws ClassNotFoundException { + return Class.forName(helper.getName(), false, loader); + } + +} + +@TargetClass(className = "io.netty.buffer.EmptyByteBuf") +final class Target_com_arangodb_shaded_netty_buffer_EmptyByteBuf { + + @Alias + @RecomputeFieldValue(kind = Kind.Reset) + private static ByteBuffer EMPTY_BYTE_BUFFER; + + @Alias + @RecomputeFieldValue(kind = Kind.Reset) + private static long EMPTY_BYTE_BUFFER_ADDRESS; + + @Substitute + public ByteBuffer nioBuffer() { + return EmptyByteBufStub.emptyByteBuffer(); + } + + @Substitute + public ByteBuffer[] nioBuffers() { + return new ByteBuffer[] { EmptyByteBufStub.emptyByteBuffer() }; + } + + @Substitute + public ByteBuffer internalNioBuffer(int index, int length) { + return EmptyByteBufStub.emptyByteBuffer(); + } + + @Substitute + public boolean hasMemoryAddress() { + return EmptyByteBufStub.emptyByteBufferAddress() != 0; + } + + @Substitute + public long memoryAddress() { + if (hasMemoryAddress()) { + return EmptyByteBufStub.emptyByteBufferAddress(); + } else { + throw new UnsupportedOperationException(); + } + } + +} + +@TargetClass(className = "io.netty.handler.codec.http.HttpContentDecompressor") +final class Target_com_arangodb_shaded_netty_handler_codec_http_HttpContentDecompressor { + + @Alias + private boolean strict; + + @Alias + protected ChannelHandlerContext ctx; + + @Substitute + protected EmbeddedChannel newContentDecoder(String contentEncoding) throws Exception { + if (GZIP.contentEqualsIgnoreCase(contentEncoding) || + X_GZIP.contentEqualsIgnoreCase(contentEncoding)) { + return new EmbeddedChannel(ctx.channel().id(), ctx.channel().metadata().hasDisconnect(), + ctx.channel().config(), ZlibCodecFactory.newZlibDecoder(ZlibWrapper.GZIP)); + } + if (DEFLATE.contentEqualsIgnoreCase(contentEncoding) || + X_DEFLATE.contentEqualsIgnoreCase(contentEncoding)) { + final ZlibWrapper wrapper = strict ? ZlibWrapper.ZLIB : ZlibWrapper.ZLIB_OR_NONE; + // To be strict, 'deflate' means ZLIB, but some servers were not implemented correctly. + return new EmbeddedChannel(ctx.channel().id(), ctx.channel().metadata().hasDisconnect(), + ctx.channel().config(), ZlibCodecFactory.newZlibDecoder(wrapper)); + } + + // 'identity' or unsupported + return null; + } +} + +@TargetClass(className = "io.netty.handler.codec.http2.DelegatingDecompressorFrameListener") +final class Target_com_arangodb_shaded_netty_handler_codec_http2_DelegatingDecompressorFrameListener { + + @Alias + boolean strict; + + @Substitute + protected EmbeddedChannel newContentDecompressor(ChannelHandlerContext ctx, CharSequence contentEncoding) + throws Http2Exception { + if (!HttpHeaderValues.GZIP.contentEqualsIgnoreCase(contentEncoding) + && !HttpHeaderValues.X_GZIP.contentEqualsIgnoreCase(contentEncoding)) { + if (!HttpHeaderValues.DEFLATE.contentEqualsIgnoreCase(contentEncoding) + && !HttpHeaderValues.X_DEFLATE.contentEqualsIgnoreCase(contentEncoding)) { + return null; + } else { + ZlibWrapper wrapper = this.strict ? ZlibWrapper.ZLIB : ZlibWrapper.ZLIB_OR_NONE; + return new EmbeddedChannel(ctx.channel().id(), ctx.channel().metadata().hasDisconnect(), ctx.channel().config(), + new ChannelHandler[] { ZlibCodecFactory.newZlibDecoder(wrapper) }); + } + } else { + return new EmbeddedChannel(ctx.channel().id(), ctx.channel().metadata().hasDisconnect(), ctx.channel().config(), + new ChannelHandler[] { ZlibCodecFactory.newZlibDecoder(ZlibWrapper.GZIP) }); + } + } +} + +@TargetClass(className = "io.netty.handler.ssl.SslHandler") +final class Target_SslHandler { + + @Substitute + private void setOpensslEngineSocketFd(Channel c) { + // do nothing. + } +} + +@TargetClass(className = "io.netty.handler.ssl.PemReader") +final class Alias_PemReader { + + @Alias + public static ByteBuf readPrivateKey(File keyFile) { + return null; + } + + @Alias + public static ByteBuf readPrivateKey(InputStream in) throws KeyException { + return null; + } +} + +/** + * If BouncyCastle is not on the classpath, we must not try to read the PEM file using the BouncyCatle PEM reader. + */ +@TargetClass(className = "io.netty.handler.ssl.SslContext", onlyWith = IsBouncyNotThere.class) +final class Target_SslContext { + + @Substitute + protected static PrivateKey toPrivateKey(File keyFile, String keyPassword) throws NoSuchAlgorithmException, + NoSuchPaddingException, InvalidKeySpecException, + InvalidAlgorithmParameterException, + KeyException, IOException { + if (keyFile == null) { + return null; + } + + return getPrivateKeyFromByteBuffer(Alias_PemReader.readPrivateKey(keyFile), keyPassword); + } + + @Substitute + protected static PrivateKey toPrivateKey(InputStream keyInputStream, String keyPassword) + throws NoSuchAlgorithmException, + NoSuchPaddingException, InvalidKeySpecException, + InvalidAlgorithmParameterException, + KeyException, IOException { + if (keyInputStream == null) { + return null; + } + + return getPrivateKeyFromByteBuffer(Alias_PemReader.readPrivateKey(keyInputStream), keyPassword); + } + + @Alias + private static PrivateKey getPrivateKeyFromByteBuffer(ByteBuf encodedKeyBuf, String keyPassword) + throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeySpecException, + InvalidAlgorithmParameterException, KeyException, IOException { + return null; + } +} + +class IsBouncyNotThere implements BooleanSupplier { + + @Override + public boolean getAsBoolean() { + try { + NettySubstitutions.class.getClassLoader().loadClass("org.bouncycastle.openssl.PEMParser"); + return false; + } catch (Exception e) { + return true; + } + } +} + +class NettySubstitutions { + +} diff --git a/shaded/src/main/java/graal/VertxSubstitutions.java b/shaded/src/main/java/graal/VertxSubstitutions.java new file mode 100644 index 000000000..14892fc8f --- /dev/null +++ b/shaded/src/main/java/graal/VertxSubstitutions.java @@ -0,0 +1,195 @@ +package graal; + +import com.oracle.svm.core.annotate.Alias; +import com.oracle.svm.core.annotate.Substitute; +import com.oracle.svm.core.annotate.TargetClass; +import io.netty.handler.ssl.*; +import io.vertx.core.MultiMap; +import io.vertx.core.Promise; +import io.vertx.core.Vertx; +import io.vertx.core.dns.AddressResolverOptions; +import io.vertx.core.eventbus.EventBusOptions; +import io.vertx.core.eventbus.impl.HandlerHolder; +import io.vertx.core.eventbus.impl.HandlerRegistration; +import io.vertx.core.eventbus.impl.MessageImpl; +import io.vertx.core.eventbus.impl.OutboundDeliveryContext; +import io.vertx.core.impl.ContextInternal; +import io.vertx.core.impl.VertxInternal; +import io.vertx.core.impl.resolver.DefaultResolverProvider; +import io.vertx.core.net.NetServerOptions; +import io.vertx.core.net.impl.transport.Transport; +import io.vertx.core.spi.resolver.ResolverProvider; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLException; +import javax.net.ssl.TrustManagerFactory; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.concurrent.ConcurrentMap; + +@TargetClass(className = "io.vertx.core.net.impl.transport.Transport") +final class Target_com_arangodb_shaded_vertx_core_net_impl_transport_Transport { + @Substitute + public static Transport nativeTransport() { + return Transport.JDK; + } +} + +/** + * This substitution forces the usage of the blocking DNS resolver + */ +@TargetClass(className = "io.vertx.core.spi.resolver.ResolverProvider") +final class TargetResolverProvider { + + @Substitute + public static ResolverProvider factory(Vertx vertx, AddressResolverOptions options) { + return new DefaultResolverProvider(); + } +} + +@TargetClass(className = "io.vertx.core.net.OpenSSLEngineOptions") +final class Target_com_arangodb_shaded_vertx_core_net_OpenSSLEngineOptions { + + @Substitute + public static boolean isAvailable() { + return false; + } + + @Substitute + public static boolean isAlpnAvailable() { + return false; + } +} + +@SuppressWarnings("rawtypes") +@TargetClass(className = "io.vertx.core.eventbus.impl.clustered.ClusteredEventBus") +final class Target_com_arangodb_shaded_vertx_core_eventbus_impl_clustered_ClusteredEventBusClusteredEventBus { + + @Substitute + private NetServerOptions getServerOptions() { + throw new RuntimeException("Not Implemented"); + } + + @Substitute + public void start(Promise promise) { + throw new RuntimeException("Not Implemented"); + } + + @Substitute + public void close(Promise promise) { + throw new RuntimeException("Not Implemented"); + } + + @Substitute + public MessageImpl createMessage(boolean send, String address, MultiMap headers, Object body, String codecName) { + throw new RuntimeException("Not Implemented"); + } + + @Substitute + protected void onLocalRegistration(HandlerHolder handlerHolder, Promise promise) { + throw new RuntimeException("Not Implemented"); + } + + @Substitute + protected HandlerHolder createHandlerHolder(HandlerRegistration registration, boolean replyHandler, + boolean localOnly, ContextInternal context) { + throw new RuntimeException("Not Implemented"); + } + + @Substitute + protected void onLocalUnregistration(HandlerHolder handlerHolder, Promise completionHandler) { + throw new RuntimeException("Not Implemented"); + } + + @Substitute + protected void sendOrPub(OutboundDeliveryContext sendContext) { + throw new RuntimeException("Not Implemented"); + } + + @Substitute + protected String generateReplyAddress() { + throw new RuntimeException("Not Implemented"); + } + + @Substitute + protected boolean isMessageLocal(MessageImpl msg) { + throw new RuntimeException("Not Implemented"); + } + + @Substitute + ConcurrentMap connections() { + throw new RuntimeException("Not Implemented"); + } + + @Substitute + VertxInternal vertx() { + throw new RuntimeException("Not Implemented"); + } + + @Substitute + EventBusOptions options() { + throw new RuntimeException("Not Implemented"); + } +} + +@TargetClass(className = "io.vertx.core.spi.tls.DefaultSslContextFactory") +final class Target_DefaultSslContextFactory { + + @Alias + private Set enabledCipherSuites; + + @Alias + private List applicationProtocols; + + @Alias + private ClientAuth clientAuth; + + @Substitute + private SslContext createContext(boolean useAlpn, boolean client, KeyManagerFactory kmf, TrustManagerFactory tmf) + throws SSLException { + SslContextBuilder builder; + if (client) { + builder = SslContextBuilder.forClient(); + if (kmf != null) { + builder.keyManager(kmf); + } + } else { + builder = SslContextBuilder.forServer(kmf); + } + Collection cipherSuites = enabledCipherSuites; + builder.sslProvider(SslProvider.JDK); + if (cipherSuites == null || cipherSuites.isEmpty()) { + cipherSuites = Target_com_arangodb_shaded_vertx_core_spi_tls_DefaultJDKCipherSuite.get(); + } + if (tmf != null) { + builder.trustManager(tmf); + } + if (cipherSuites != null && cipherSuites.size() > 0) { + builder.ciphers(cipherSuites); + } + if (useAlpn && applicationProtocols != null && applicationProtocols.size() > 0) { + builder.applicationProtocolConfig(new ApplicationProtocolConfig( + ApplicationProtocolConfig.Protocol.ALPN, + ApplicationProtocolConfig.SelectorFailureBehavior.NO_ADVERTISE, + ApplicationProtocolConfig.SelectedListenerFailureBehavior.ACCEPT, + applicationProtocols)); + } + if (clientAuth != null) { + builder.clientAuth(clientAuth); + } + return builder.build(); + } +} + +@TargetClass(className = "io.vertx.core.spi.tls.DefaultJDKCipherSuite") +final class Target_com_arangodb_shaded_vertx_core_spi_tls_DefaultJDKCipherSuite { + @Alias + static List get() { + return null; + } +} + +class VertxSubstitutions { + +} diff --git a/shaded/src/main/java/graal/ZLibSubstitutions.java b/shaded/src/main/java/graal/ZLibSubstitutions.java new file mode 100644 index 000000000..af131b702 --- /dev/null +++ b/shaded/src/main/java/graal/ZLibSubstitutions.java @@ -0,0 +1,66 @@ +package graal; + +import com.oracle.svm.core.annotate.Substitute; +import com.oracle.svm.core.annotate.TargetClass; +import io.netty.handler.codec.compression.*; + +/** + * This substitution avoid having jcraft zlib added to the build + */ +@TargetClass(className = "io.netty.handler.codec.compression.ZlibCodecFactory") +final class Target_com_arangodb_shaded_netty_handler_codec_compression_ZlibCodecFactory { + + @Substitute + public static ZlibEncoder newZlibEncoder(int compressionLevel) { + return new JdkZlibEncoder(compressionLevel); + } + + @Substitute + public static ZlibEncoder newZlibEncoder(ZlibWrapper wrapper) { + return new JdkZlibEncoder(wrapper); + } + + @Substitute + public static ZlibEncoder newZlibEncoder(ZlibWrapper wrapper, int compressionLevel) { + return new JdkZlibEncoder(wrapper, compressionLevel); + } + + @Substitute + public static ZlibEncoder newZlibEncoder(ZlibWrapper wrapper, int compressionLevel, int windowBits, int memLevel) { + return new JdkZlibEncoder(wrapper, compressionLevel); + } + + @Substitute + public static ZlibEncoder newZlibEncoder(byte[] dictionary) { + return new JdkZlibEncoder(dictionary); + } + + @Substitute + public static ZlibEncoder newZlibEncoder(int compressionLevel, byte[] dictionary) { + return new JdkZlibEncoder(compressionLevel, dictionary); + } + + @Substitute + public static ZlibEncoder newZlibEncoder(int compressionLevel, int windowBits, int memLevel, byte[] dictionary) { + return new JdkZlibEncoder(compressionLevel, dictionary); + } + + @Substitute + public static ZlibDecoder newZlibDecoder() { + return new JdkZlibDecoder(); + } + + @Substitute + public static ZlibDecoder newZlibDecoder(ZlibWrapper wrapper) { + return new JdkZlibDecoder(wrapper); + } + + @Substitute + public static ZlibDecoder newZlibDecoder(byte[] dictionary) { + return new JdkZlibDecoder(dictionary); + } +} + +class ZLibSubstitutions { + +} diff --git a/shaded/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver-shaded/native-image.properties b/shaded/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver-shaded/native-image.properties index 9ff995ecd..8a2425d56 100644 --- a/shaded/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver-shaded/native-image.properties +++ b/shaded/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver-shaded/native-image.properties @@ -1,11 +1,39 @@ Args=\ -H:ResourceConfigurationResources=${.}/resource-config.json,${.}/resource-config-spi.json \ --H:ReflectionConfigurationResources=${.}/reflect-config.json,${.}/reflect-config-spi.json,${.}/reflect-config-mp-config.json,${.}/netty-reflect-config.json \ +-H:ReflectionConfigurationResources=${.}/reflect-config.json,${.}/reflect-config-spi.json,${.}/reflect-config-mp-config.json,${.}/reflect-config-netty.json \ -H:SerializationConfigurationResources=${.}/serialization-config.json \ +-Dcom.arangodb.shaded.netty.noUnsafe=true \ +-Dcom.arangodb.shaded.netty.leakDetection.level=DISABLED \ --initialize-at-build-time=\ - org.slf4j \ + org.slf4j,\ + com.arangodb.shaded.netty \ --initialize-at-run-time=\ - com.arangodb.shaded.netty.handler.ssl.BouncyCastleAlpnSslUtils,\ - com.arangodb.shaded.netty.handler.codec.compression.ZstdOptions \ --Dcom.arangodb.shaded.netty.noUnsafe=true \ --Dcom.arangodb.shaded.netty.leakDetection.level=DISABLED + com.arangodb.shaded.netty.buffer.AbstractReferenceCountedByteBuf,\ + com.arangodb.shaded.netty.buffer.ByteBufAllocator,\ + com.arangodb.shaded.netty.buffer.ByteBufUtil,\ + com.arangodb.shaded.netty.buffer.PooledByteBufAllocator,\ + com.arangodb.shaded.netty.handler.codec.compression.Brotli,\ + com.arangodb.shaded.netty.handler.codec.compression.BrotliDecoder,\ + com.arangodb.shaded.netty.handler.codec.compression.BrotliOptions,\ + com.arangodb.shaded.netty.handler.codec.compression.ZstdOptions,\ + com.arangodb.shaded.netty.handler.codec.http.HttpObjectEncoder,\ + com.arangodb.shaded.netty.handler.codec.http.websocketx.extensions.compression.DeflateDecoder,\ + com.arangodb.shaded.netty.handler.codec.http.websocketx.WebSocket00FrameEncoder,\ + com.arangodb.shaded.netty.handler.codec.http2.DefaultHttp2FrameWriter,\ + com.arangodb.shaded.netty.handler.codec.http2.Http2ClientUpgradeCodec,\ + com.arangodb.shaded.netty.handler.codec.http2.Http2CodecUtil,\ + com.arangodb.shaded.netty.handler.codec.http2.Http2ConnectionHandler,\ + com.arangodb.shaded.netty.handler.ssl.BouncyCastleAlpnSslUtils,\ + com.arangodb.shaded.netty.handler.ssl.util.ThreadLocalInsecureRandom,\ + com.arangodb.shaded.netty.resolver.dns.DefaultDnsServerAddressStreamProvider,\ + com.arangodb.shaded.netty.resolver.dns.DnsNameResolver,\ + com.arangodb.shaded.netty.resolver.dns.DnsServerAddressStreamProviders$DefaultProviderHolder,\ + com.arangodb.shaded.netty.resolver.HostsFileEntriesResolver,\ + com.arangodb.shaded.netty.util.AbstractReferenceCounted,\ + com.arangodb.shaded.netty.util.concurrent.GlobalEventExecutor,\ + com.arangodb.shaded.netty.util.concurrent.ImmediateEventExecutor,\ + com.arangodb.shaded.netty.util.concurrent.ScheduledFutureTask,\ + com.arangodb.shaded.netty.util.internal.ThreadLocalRandom,\ + com.arangodb.shaded.netty.util.NetUtilSubstitutions$NetUtilLocalhost4LazyHolder,\ + com.arangodb.shaded.netty.util.NetUtilSubstitutions$NetUtilLocalhost6LazyHolder,\ + com.arangodb.shaded.netty.util.NetUtilSubstitutions$NetUtilLocalhostLazyHolder diff --git a/shaded/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver-shaded/netty-reflect-config.json b/shaded/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver-shaded/reflect-config-netty.json similarity index 100% rename from shaded/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver-shaded/netty-reflect-config.json rename to shaded/src/main/resources/META-INF/native-image/com.arangodb/arangodb-java-driver-shaded/reflect-config-netty.json From ecd92f7f2326a69046a266d8b3638a37a2f1f685 Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Fri, 3 Mar 2023 22:24:02 +0100 Subject: [PATCH 08/12] plain integration tests --- .github/workflows/native.yml | 4 +- .github/workflows/test.yml | 11 ++-- driver/pom.xml | 2 +- .../pom.xml | 61 ++++++++++++++++++- .../src/test/internal/java/arch/AdbTest.java | 0 .../src/test/internal/java/arch/BaseTest.java | 0 .../test/internal/java/arch/ConfigUtils.java | 0 .../src/test/internal/java/arch/Person.java | 0 .../internal/java/arch/RelocationsTest.java | 0 .../test/internal/java/arch/SerdeTest.java | 0 .../src/test/jackson/java/arch/AdbTest.java | 0 .../src/test/jackson/java/arch/BaseTest.java | 0 .../test/jackson/java/arch/ConfigUtils.java | 0 .../src/test/jackson/java/arch/Person.java | 0 .../jackson/java/arch/RelocationsTest.java | 0 .../src/test/jackson/java/arch/SerdeTest.java | 0 .../src/test/jsonb/java/arch/AdbTest.java | 0 .../src/test/jsonb/java/arch/BaseTest.java | 0 .../src/test/jsonb/java/arch/ConfigUtils.java | 0 .../src/test/jsonb/java/arch/Person.java | 0 .../test/jsonb/java/arch/RelocationsTest.java | 0 .../src/test/jsonb/java/arch/SerdeTest.java | 0 .../src/test/plain}/java/com | 0 .../src/test/resources | 0 24 files changed, 69 insertions(+), 9 deletions(-) rename {shaded-integration-tests => integration-tests}/pom.xml (76%) rename {shaded-integration-tests => integration-tests}/src/test/internal/java/arch/AdbTest.java (100%) rename {shaded-integration-tests => integration-tests}/src/test/internal/java/arch/BaseTest.java (100%) rename {shaded-integration-tests => integration-tests}/src/test/internal/java/arch/ConfigUtils.java (100%) rename {shaded-integration-tests => integration-tests}/src/test/internal/java/arch/Person.java (100%) rename {shaded-integration-tests => integration-tests}/src/test/internal/java/arch/RelocationsTest.java (100%) rename {shaded-integration-tests => integration-tests}/src/test/internal/java/arch/SerdeTest.java (100%) rename {shaded-integration-tests => integration-tests}/src/test/jackson/java/arch/AdbTest.java (100%) rename {shaded-integration-tests => integration-tests}/src/test/jackson/java/arch/BaseTest.java (100%) rename {shaded-integration-tests => integration-tests}/src/test/jackson/java/arch/ConfigUtils.java (100%) rename {shaded-integration-tests => integration-tests}/src/test/jackson/java/arch/Person.java (100%) rename {shaded-integration-tests => integration-tests}/src/test/jackson/java/arch/RelocationsTest.java (100%) rename {shaded-integration-tests => integration-tests}/src/test/jackson/java/arch/SerdeTest.java (100%) rename {shaded-integration-tests => integration-tests}/src/test/jsonb/java/arch/AdbTest.java (100%) rename {shaded-integration-tests => integration-tests}/src/test/jsonb/java/arch/BaseTest.java (100%) rename {shaded-integration-tests => integration-tests}/src/test/jsonb/java/arch/ConfigUtils.java (100%) rename {shaded-integration-tests => integration-tests}/src/test/jsonb/java/arch/Person.java (100%) rename {shaded-integration-tests => integration-tests}/src/test/jsonb/java/arch/RelocationsTest.java (100%) rename {shaded-integration-tests => integration-tests}/src/test/jsonb/java/arch/SerdeTest.java (100%) rename {shaded-integration-tests/src/test/native => integration-tests/src/test/plain}/java/com (100%) rename {shaded-integration-tests => integration-tests}/src/test/resources (100%) diff --git a/.github/workflows/native.yml b/.github/workflows/native.yml index 9df54ccf5..879cfa61f 100644 --- a/.github/workflows/native.yml +++ b/.github/workflows/native.yml @@ -21,7 +21,7 @@ jobs: - 17 module: - driver - - shaded-integration-tests + - integration-tests steps: - uses: actions/checkout@v2 @@ -60,7 +60,7 @@ jobs: - 17 module: - driver - - shaded-integration-tests + - integration-tests steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d4bef6589..2b5d4f020 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -222,7 +222,7 @@ jobs: - name: Test run: mvn --no-transfer-progress -am -pl driver test -Dadb.jackson.version=${{matrix.jackson-version}} - shaded-integration-tests: + integration-tests: timeout-minutes: 20 runs-on: ubuntu-latest @@ -255,14 +255,17 @@ jobs: - name: Install run: mvn --no-transfer-progress install -DskipTests=true -Dgpg.skip=true -Dmaven.javadoc.skip=true - name: Test internal-serde - working-directory: shaded-integration-tests + working-directory: integration-tests run: mvn --no-transfer-progress -Pinternal-serde test - name: Test jackson-serde - working-directory: shaded-integration-tests + working-directory: integration-tests run: mvn --no-transfer-progress -Pjackson-serde test - name: Test jsonb-serde - working-directory: shaded-integration-tests + working-directory: integration-tests run: mvn --no-transfer-progress -Pjsonb-serde test + - name: Test plain + working-directory: integration-tests + run: mvn --no-transfer-progress -Pplain test sonar: timeout-minutes: 10 diff --git a/driver/pom.xml b/driver/pom.xml index ee59d9e42..003ef92fc 100644 --- a/driver/pom.xml +++ b/driver/pom.xml @@ -154,7 +154,7 @@ org.graalvm.sdk graal-sdk - 22.3.0 + 22.3.1 test diff --git a/shaded-integration-tests/pom.xml b/integration-tests/pom.xml similarity index 76% rename from shaded-integration-tests/pom.xml rename to integration-tests/pom.xml index 2c7e8da7f..42acfe51c 100644 --- a/shaded-integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -10,7 +10,7 @@ 7.0.0-ALPHA.2 - shaded-integration-tests + integration-tests 17 @@ -29,6 +29,34 @@ + + org.apache.maven.plugins + maven-enforcer-plugin + 3.1.0 + + + enforce-bytecode-version + + enforce + + + + + 1.8 + + + true + + + + + + org.codehaus.mojo + extra-enforcer-rules + 1.6.1 + + + @@ -145,7 +173,7 @@ - ${project.basedir}/src/test/native/java + ${project.basedir}/src/test/plain/java ** ${project.build.directory}/generated-test-sources replacer @@ -185,6 +213,35 @@ + + plain + + src/test/plain/java + jackson + + + + com.arangodb + arangodb-java-driver + + + com.arangodb + http-protocol + + + com.arangodb + vst-protocol + + + com.arangodb + jackson-serde-json + + + com.arangodb + jackson-serde-vpack + + + \ No newline at end of file diff --git a/shaded-integration-tests/src/test/internal/java/arch/AdbTest.java b/integration-tests/src/test/internal/java/arch/AdbTest.java similarity index 100% rename from shaded-integration-tests/src/test/internal/java/arch/AdbTest.java rename to integration-tests/src/test/internal/java/arch/AdbTest.java diff --git a/shaded-integration-tests/src/test/internal/java/arch/BaseTest.java b/integration-tests/src/test/internal/java/arch/BaseTest.java similarity index 100% rename from shaded-integration-tests/src/test/internal/java/arch/BaseTest.java rename to integration-tests/src/test/internal/java/arch/BaseTest.java diff --git a/shaded-integration-tests/src/test/internal/java/arch/ConfigUtils.java b/integration-tests/src/test/internal/java/arch/ConfigUtils.java similarity index 100% rename from shaded-integration-tests/src/test/internal/java/arch/ConfigUtils.java rename to integration-tests/src/test/internal/java/arch/ConfigUtils.java diff --git a/shaded-integration-tests/src/test/internal/java/arch/Person.java b/integration-tests/src/test/internal/java/arch/Person.java similarity index 100% rename from shaded-integration-tests/src/test/internal/java/arch/Person.java rename to integration-tests/src/test/internal/java/arch/Person.java diff --git a/shaded-integration-tests/src/test/internal/java/arch/RelocationsTest.java b/integration-tests/src/test/internal/java/arch/RelocationsTest.java similarity index 100% rename from shaded-integration-tests/src/test/internal/java/arch/RelocationsTest.java rename to integration-tests/src/test/internal/java/arch/RelocationsTest.java diff --git a/shaded-integration-tests/src/test/internal/java/arch/SerdeTest.java b/integration-tests/src/test/internal/java/arch/SerdeTest.java similarity index 100% rename from shaded-integration-tests/src/test/internal/java/arch/SerdeTest.java rename to integration-tests/src/test/internal/java/arch/SerdeTest.java diff --git a/shaded-integration-tests/src/test/jackson/java/arch/AdbTest.java b/integration-tests/src/test/jackson/java/arch/AdbTest.java similarity index 100% rename from shaded-integration-tests/src/test/jackson/java/arch/AdbTest.java rename to integration-tests/src/test/jackson/java/arch/AdbTest.java diff --git a/shaded-integration-tests/src/test/jackson/java/arch/BaseTest.java b/integration-tests/src/test/jackson/java/arch/BaseTest.java similarity index 100% rename from shaded-integration-tests/src/test/jackson/java/arch/BaseTest.java rename to integration-tests/src/test/jackson/java/arch/BaseTest.java diff --git a/shaded-integration-tests/src/test/jackson/java/arch/ConfigUtils.java b/integration-tests/src/test/jackson/java/arch/ConfigUtils.java similarity index 100% rename from shaded-integration-tests/src/test/jackson/java/arch/ConfigUtils.java rename to integration-tests/src/test/jackson/java/arch/ConfigUtils.java diff --git a/shaded-integration-tests/src/test/jackson/java/arch/Person.java b/integration-tests/src/test/jackson/java/arch/Person.java similarity index 100% rename from shaded-integration-tests/src/test/jackson/java/arch/Person.java rename to integration-tests/src/test/jackson/java/arch/Person.java diff --git a/shaded-integration-tests/src/test/jackson/java/arch/RelocationsTest.java b/integration-tests/src/test/jackson/java/arch/RelocationsTest.java similarity index 100% rename from shaded-integration-tests/src/test/jackson/java/arch/RelocationsTest.java rename to integration-tests/src/test/jackson/java/arch/RelocationsTest.java diff --git a/shaded-integration-tests/src/test/jackson/java/arch/SerdeTest.java b/integration-tests/src/test/jackson/java/arch/SerdeTest.java similarity index 100% rename from shaded-integration-tests/src/test/jackson/java/arch/SerdeTest.java rename to integration-tests/src/test/jackson/java/arch/SerdeTest.java diff --git a/shaded-integration-tests/src/test/jsonb/java/arch/AdbTest.java b/integration-tests/src/test/jsonb/java/arch/AdbTest.java similarity index 100% rename from shaded-integration-tests/src/test/jsonb/java/arch/AdbTest.java rename to integration-tests/src/test/jsonb/java/arch/AdbTest.java diff --git a/shaded-integration-tests/src/test/jsonb/java/arch/BaseTest.java b/integration-tests/src/test/jsonb/java/arch/BaseTest.java similarity index 100% rename from shaded-integration-tests/src/test/jsonb/java/arch/BaseTest.java rename to integration-tests/src/test/jsonb/java/arch/BaseTest.java diff --git a/shaded-integration-tests/src/test/jsonb/java/arch/ConfigUtils.java b/integration-tests/src/test/jsonb/java/arch/ConfigUtils.java similarity index 100% rename from shaded-integration-tests/src/test/jsonb/java/arch/ConfigUtils.java rename to integration-tests/src/test/jsonb/java/arch/ConfigUtils.java diff --git a/shaded-integration-tests/src/test/jsonb/java/arch/Person.java b/integration-tests/src/test/jsonb/java/arch/Person.java similarity index 100% rename from shaded-integration-tests/src/test/jsonb/java/arch/Person.java rename to integration-tests/src/test/jsonb/java/arch/Person.java diff --git a/shaded-integration-tests/src/test/jsonb/java/arch/RelocationsTest.java b/integration-tests/src/test/jsonb/java/arch/RelocationsTest.java similarity index 100% rename from shaded-integration-tests/src/test/jsonb/java/arch/RelocationsTest.java rename to integration-tests/src/test/jsonb/java/arch/RelocationsTest.java diff --git a/shaded-integration-tests/src/test/jsonb/java/arch/SerdeTest.java b/integration-tests/src/test/jsonb/java/arch/SerdeTest.java similarity index 100% rename from shaded-integration-tests/src/test/jsonb/java/arch/SerdeTest.java rename to integration-tests/src/test/jsonb/java/arch/SerdeTest.java diff --git a/shaded-integration-tests/src/test/native/java/com b/integration-tests/src/test/plain/java/com similarity index 100% rename from shaded-integration-tests/src/test/native/java/com rename to integration-tests/src/test/plain/java/com diff --git a/shaded-integration-tests/src/test/resources b/integration-tests/src/test/resources similarity index 100% rename from shaded-integration-tests/src/test/resources rename to integration-tests/src/test/resources From 9e049fe6e5c597978752ea8f2e99e291325768ef Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Fri, 3 Mar 2023 22:29:15 +0100 Subject: [PATCH 09/12] rm java 8 from CI --- .github/workflows/maven-deploy.yml | 2 +- .github/workflows/maven-release.yml | 2 +- .github/workflows/test.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/maven-deploy.yml b/.github/workflows/maven-deploy.yml index f7532d404..acca6dc1e 100644 --- a/.github/workflows/maven-deploy.yml +++ b/.github/workflows/maven-deploy.yml @@ -18,7 +18,7 @@ jobs: - name: Set up JDK uses: actions/setup-java@v3 with: - java-version: '8' + java-version: '11' distribution: 'adopt' cache: 'maven' server-id: ossrh diff --git a/.github/workflows/maven-release.yml b/.github/workflows/maven-release.yml index 61217e1b3..f8604f238 100644 --- a/.github/workflows/maven-release.yml +++ b/.github/workflows/maven-release.yml @@ -18,7 +18,7 @@ jobs: - name: Set up JDK uses: actions/setup-java@v3 with: - java-version: '8' + java-version: '11' distribution: 'adopt' cache: 'maven' server-id: ossrh diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2b5d4f020..05144f993 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -46,7 +46,7 @@ jobs: db-ext-names: - false java-version: - - 8 + - 11 user-language: - en include: From 461b1c39f449654efd74bbeb7809bfd3a282c67f Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Fri, 3 Mar 2023 22:59:26 +0100 Subject: [PATCH 10/12] fix enforcer checks --- integration-tests/pom.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index 42acfe51c..f6c6a2ebc 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -43,6 +43,9 @@ 1.8 + + com.tngtech.archunit:archunit + true From 2a262b4b53862326ae3f346c5bf2a61cacca4c29 Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Sat, 4 Mar 2023 21:00:44 +0100 Subject: [PATCH 11/12] fix enforcer checks --- integration-tests/pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml index f6c6a2ebc..47f9b220f 100644 --- a/integration-tests/pom.xml +++ b/integration-tests/pom.xml @@ -45,6 +45,8 @@ 1.8 com.tngtech.archunit:archunit + org.eclipse:yasson + jakarta.json.bind:jakarta.json.bind-api From 4d4c1c42f278d9e93cbbc6e0d4cb951ec3468d59 Mon Sep 17 00:00:00 2001 From: Michele Rastelli Date: Mon, 6 Mar 2023 11:34:11 +0100 Subject: [PATCH 12/12] native tests with single server --- .github/workflows/native.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/native.yml b/.github/workflows/native.yml index 879cfa61f..c882a7864 100644 --- a/.github/workflows/native.yml +++ b/.github/workflows/native.yml @@ -16,7 +16,7 @@ jobs: docker-img: - docker.io/arangodb/enterprise:3.10.1 topology: - - cluster + - single java-version: - 17 module: