diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 40536225f..95588a991 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -32,7 +32,7 @@ jobs: test-linux: needs: build - name: ${{ matrix.cloud }} JDBC ${{ matrix.category }} on ${{ matrix.image }} + name: ${{ matrix.cloud }} JDBC${{ matrix.additionalMavenProfile }} ${{ matrix.category }} on ${{ matrix.image }} runs-on: ubuntu-latest strategy: fail-fast: false @@ -40,6 +40,7 @@ jobs: image: [ 'jdbc-centos7-openjdk8', 'jdbc-centos7-openjdk11', 'jdbc-centos7-openjdk17' ] cloud: [ 'AWS' ] category: ['TestCategoryResultSet,TestCategoryOthers,TestCategoryLoader', 'TestCategoryConnection,TestCategoryStatement', 'TestCategoryArrow,TestCategoryCore', 'TestCategoryFips'] + additionalMavenProfile: ['', '-Dthin-jar'] steps: - uses: actions/checkout@v1 - name: Tests @@ -49,6 +50,7 @@ jobs: CLOUD_PROVIDER: ${{ matrix.cloud }} TARGET_DOCKER_TEST_IMAGE: ${{ matrix.image }} JDBC_TEST_CATEGORY: ${{ matrix.category }} + ADDITIONAL_MAVEN_PROFILE: ${{ matrix.additionalMavenProfile }} run: ./ci/test.sh test-linux-old-driver: diff --git a/README.rst b/README.rst index d04a7e003..790ddbaa0 100644 --- a/README.rst +++ b/README.rst @@ -111,6 +111,17 @@ You may import the coding style from IntelliJ so that the coding style can be ap - Enable `google-java-format` for the JDBC project. - In the source code window, select **Code** -> **Reformat** to apply the coding style. +Thin Jar +======== + +To build a thin jar run command: + +.. code-block:: bash + + mvn clean verify -Dthin-jar -Dnot-self-contained-jar + +- `thin-jar` enables thin jar profile +- `not-self-contained-jar` turns off fat jar profile (enabled by default) Tests ===== diff --git a/ci/container/test_component.sh b/ci/container/test_component.sh index 8757532cd..1b7ea83f3 100755 --- a/ci/container/test_component.sh +++ b/ci/container/test_component.sh @@ -104,7 +104,7 @@ for c in "${CATEGORY[@]}"; do -Djacoco.skip.instrument=false \ -DtestCategory=net.snowflake.client.category.$c \ -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn \ - -Dnot-self-contained-jar \ + -Dnot-self-contained-jar $ADDITIONAL_MAVEN_PROFILE \ verify \ --batch-mode --show-version fi diff --git a/ci/scripts/check_content.sh b/ci/scripts/check_content.sh index b2dbd68ea..d2922fe7a 100755 --- a/ci/scripts/check_content.sh +++ b/ci/scripts/check_content.sh @@ -2,11 +2,13 @@ # scripts used to check if all dependency is shaded into snowflake internal path +package_modifier=$1 + set -o pipefail DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )" -if jar tvf $DIR/../../target/snowflake-jdbc.jar | awk '{print $8}' | grep -v -E "^(net|com)/snowflake" | grep -v -E "(com|net)/\$" | grep -v -E "^META-INF" | grep -v -E "^mozilla" | grep -v -E "^com/sun/jna" | grep -v com/sun/ | grep -v mime.types; then +if jar tvf $DIR/../../target/snowflake-jdbc${package_modifier}.jar | awk '{print $8}' | grep -v -E "^(net|com)/snowflake" | grep -v -E "(com|net)/\$" | grep -v -E "^META-INF" | grep -v -E "^mozilla" | grep -v -E "^com/sun/jna" | grep -v com/sun/ | grep -v mime.types; then echo "[ERROR] JDBC jar includes class not under the snowflake namespace" exit 1 fi diff --git a/ci/test.sh b/ci/test.sh index 273d236b2..49a999d41 100755 --- a/ci/test.sh +++ b/ci/test.sh @@ -57,6 +57,7 @@ for name in "${!TARGET_TEST_IMAGES[@]}"; do -e JOB_NAME \ -e BUILD_NUMBER \ -e JDBC_TEST_CATEGORY \ + -e ADDITIONAL_MAVEN_PROFILE \ -e is_old_driver \ --add-host=snowflake.reg.local:${IP_ADDR} \ --add-host=s3testaccount.reg.local:${IP_ADDR} \ diff --git a/pom.xml b/pom.xml index 8cd0da885..b5c864b98 100644 --- a/pom.xml +++ b/pom.xml @@ -10,11 +10,12 @@ ./parent-pom.xml - snowflake-jdbc + + ${artifactId} 3.14.4 jar - snowflake-jdbc + ${artifactId} https://github.com/snowflakedb/snowflake-jdbc @@ -22,6 +23,10 @@ https://github.com/snowflakedb/snowflake-jdbc + + snowflake-jdbc + + org.bouncycastle @@ -578,6 +583,195 @@ + + thin-jar + + + thin-jar + + + + snowflake-jdbc-thin + + + + + + com.github.siom79.japicmp + japicmp-maven-plugin + + + japicmp + + cmp + + none + + + + + + + org.apache.maven.plugins + maven-antrun-plugin + + + repack + + run + + package + + + + + + + + + + + + + + + + + + org.apache.maven.plugins + maven-enforcer-plugin + + + enforce-linkage-checker + + enforce + + none + + + + + org.apache.maven.plugins + maven-shade-plugin + + + + + shade + + package + + + + net.snowflake:snowflake-common + org.apache.arrow:* + org.apache.tika:tika-core + io.netty:* + + + + + + net.snowflake.common + ${shadeBase}.snowflake.common + + + org.apache.arrow + ${shadeBase}.apache.arrow + + + org.apache.tika + ${shadeBase}.apache.tika + + + + io.netty + ${shadeBase}.io.netty + + + + + *:* + + META-INF/LICENSE* + META-INF/NOTICE* + META-INF/DEPENDENCIES + META-INF/maven/** + META-INF/services/com.fasterxml.* + META-INF/*.xml + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + .netbeans_automatic_build + git.properties + arrow-git.properties + google-http-client.properties + storage.v1.json + + pipes-fork-server-default-log4j2.xml + dependencies.properties + pipes-fork-server-default-log4j2.xml + + + + org.apache.arrow:arrow-vector + + + codegen/** + + + + + + + + + + + + + org.codehaus.mojo + buildnumber-maven-plugin + + yyyyMMddHHmmss + buildNumber.timestamp + false + + false + + + + + + create-timestamp + + package + + + + + org.codehaus.mojo + exec-maven-plugin + + + check-shaded-content + + exec + + verify + + ${basedir}/ci/scripts/check_content.sh + + -thin + + + + + + + + self-contained-jar diff --git a/src/test/java/net/snowflake/client/SkipOnThinJar.java b/src/test/java/net/snowflake/client/SkipOnThinJar.java new file mode 100644 index 000000000..d02d104dd --- /dev/null +++ b/src/test/java/net/snowflake/client/SkipOnThinJar.java @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2012-2024 Snowflake Computing Inc. All right reserved. + */ +package net.snowflake.client; + +/** Skip tests on CI when thin jar is tested */ +public class SkipOnThinJar implements ConditionalIgnoreRule.IgnoreCondition { + @Override + public boolean isSatisfied() { + return "-Dthin-jar".equals(TestUtil.systemGetEnv("ADDITIONAL_MAVEN_PROFILE")); + } +} diff --git a/src/test/java/net/snowflake/client/core/SFArrowResultSetIT.java b/src/test/java/net/snowflake/client/core/SFArrowResultSetIT.java index 9aae0bcf6..63200c70f 100644 --- a/src/test/java/net/snowflake/client/core/SFArrowResultSetIT.java +++ b/src/test/java/net/snowflake/client/core/SFArrowResultSetIT.java @@ -17,6 +17,8 @@ import java.sql.Statement; import java.time.Instant; import java.util.*; +import net.snowflake.client.ConditionalIgnoreRule; +import net.snowflake.client.SkipOnThinJar; import net.snowflake.client.category.TestCategoryArrow; import net.snowflake.client.jdbc.*; import net.snowflake.client.jdbc.telemetry.NoOpTelemetryClient; @@ -41,9 +43,16 @@ @Category(TestCategoryArrow.class) public class SFArrowResultSetIT { + + /** Necessary to conditional ignore tests */ + @Rule public ConditionalIgnoreRule rule = new ConditionalIgnoreRule(); + private Random random = new Random(); - /** allocator for arrow */ + /** + * allocator for arrow RootAllocator is shaded so it cannot be overridden when testing thin or fat + * jar + */ protected BufferAllocator allocator = new RootAllocator(Long.MAX_VALUE); /** temporary folder to store result files */ @@ -51,6 +60,7 @@ public class SFArrowResultSetIT { /** Test the case that all results are returned in first chunk */ @Test + @ConditionalIgnoreRule.ConditionalIgnore(condition = SkipOnThinJar.class) public void testNoOfflineData() throws Throwable { List fieldList = new ArrayList<>(); Map customFieldMeta = new HashMap<>(); @@ -112,6 +122,7 @@ public void testEmptyResultSet() throws Throwable { /** Testing the case that all data comes from chunk downloader */ @Test + @ConditionalIgnoreRule.ConditionalIgnore(condition = SkipOnThinJar.class) public void testOnlyOfflineData() throws Throwable { final int colCount = 2; final int chunkCount = 10; @@ -161,6 +172,7 @@ public void testOnlyOfflineData() throws Throwable { /** Testing the case that all data comes from chunk downloader */ @Test + @ConditionalIgnoreRule.ConditionalIgnore(condition = SkipOnThinJar.class) public void testFirstResponseAndOfflineData() throws Throwable { final int colCount = 2; final int chunkCount = 10; @@ -553,6 +565,7 @@ private void writeTimestampStructToField( /** Test that first chunk containing struct vectors (used for timestamps) can be sorted */ @Test + @ConditionalIgnoreRule.ConditionalIgnore(condition = SkipOnThinJar.class) public void testSortedResultChunkWithStructVectors() throws Throwable { Connection con = getConnection(); Statement statement = con.createStatement(); @@ -622,6 +635,7 @@ public void testSortedResultChunkWithStructVectors() throws Throwable { /** Test that the first chunk can be sorted */ @Test + @ConditionalIgnoreRule.ConditionalIgnore(condition = SkipOnThinJar.class) public void testSortedResultChunk() throws Throwable { Connection con = getConnection(); Statement statement = con.createStatement(); diff --git a/thin_public_pom.xml b/thin_public_pom.xml new file mode 100644 index 000000000..0503b71df --- /dev/null +++ b/thin_public_pom.xml @@ -0,0 +1,267 @@ + + + 4.0.0 + + net.snowflake + snowflake-jdbc-thin + 1.0-SNAPSHOT + jar + Snowflake JDBC Driver Thin + Snowflake JDBC Driver Thin + https://www.snowflake.net/ + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + + + + + + Snowflake Support Team + snowflake-java@snowflake.net + Snowflake Computing + https://www.snowflake.net + + + + + scm:git:git://github.com/snowflakedb/snowflake-jdbc + http://github.com/snowflakedb/snowflake-jdbc/tree/master + + + + 4.5.14 + 4.4.16 + 1.12.501 + 5.0.0 + 1.74 + 1.15 + 2.11.0 + 1.2 + 2.21.0 + 2.22.6 + 1.12.0 + 2.31.0 + 32.1.1-jre + 1.43.3 + 3.0.2 + 3.23.3 + 1.60.0 + 2.15.3 + 3.1.0 + 5.13.0 + 2.8.1 + 2.4.9 + 1.15.3 + 2.2.0 + 4.1.100.Final + 9.21 + UTF-8 + UTF-8 + 2.0.6 + + + + + + com.amazonaws + aws-java-sdk-bom + ${awssdk.version} + pom + import + + + com.fasterxml.jackson + jackson-bom + ${jackson.version} + pom + import + + + com.google.http-client + google-http-client-bom + ${google.http.client.version} + pom + import + + + com.google.protobuf + protobuf-bom + ${google.protobuf.java.version} + pom + import + + + io.grpc + grpc-bom + ${grpc.version} + pom + import + + + + + + + org.bouncycastle + bcpkix-jdk18on + ${bouncycastle.version} + + + org.bouncycastle + bcprov-jdk18on + ${bouncycastle.version} + + + com.amazonaws + aws-java-sdk-core + + + com.amazonaws + aws-java-sdk-kms + + + com.amazonaws + aws-java-sdk-s3 + + + com.fasterxml.jackson.core + jackson-annotations + + + com.fasterxml.jackson.core + jackson-core + + + com.fasterxml.jackson.core + jackson-databind + + + com.google.api + gax + ${google.gax.version} + + + com.google.cloud + google-cloud-core + ${google.cloud.core.version} + + + com.google.cloud + google-cloud-storage + ${google.cloud.storage.version} + + + com.google.code.findbugs + jsr305 + ${google.jsr305.version} + + + com.google.guava + guava + ${google.guava.version} + + + com.google.http-client + google-http-client + + + com.microsoft.azure + azure-storage + ${azure.storage.version} + + + com.nimbusds + nimbus-jose-jwt + ${nimbusds.version} + + + com.yammer.metrics + metrics-core + ${metrics.version} + + + com.yammer.metrics + metrics-servlet + ${metrics.version} + + + commons-codec + commons-codec + ${commons.codec.version} + + + commons-io + commons-io + ${commons.io.version} + + + commons-logging + commons-logging + ${commons.logging.version} + + + javax.servlet + javax.servlet-api + ${javax.servlet.version} + + + joda-time + joda-time + ${joda.time.version} + + + net.java.dev.jna + jna + ${jna.version} + true + + + net.java.dev.jna + jna-platform + ${jna.version} + true + + + net.minidev + json-smart + ${json.smart.version} + + + org.apache.httpcomponents + httpclient + ${apache.httpclient.version} + + + org.apache.httpcomponents + httpcore + ${apache.httpcore.version} + + + org.jsoup + jsoup + ${jsoup.version} + + + org.slf4j + slf4j-api + ${slf4j.version} + provided + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + runtime + + + + com.google.flatbuffers + flatbuffers-java + ${google.flatbuffers.version} + + + +