diff --git a/pom.xml b/pom.xml index 97c020916..fc46b2952 100644 --- a/pom.xml +++ b/pom.xml @@ -426,6 +426,32 @@ + + + alt_build_dir + + + alt.build.dir + + + + ${alt.build.dir} + + + org.apache.maven.plugins + maven-shade-plugin + 3.6.0 + + + + ${alt.build.dir}/single.jar + + + + + + + diff --git a/src/test/java/com/google/cloud/spanner/jdbc/SingleJarTestApplication.java b/src/test/java/com/google/cloud/spanner/jdbc/SingleJarTestApplication.java new file mode 100644 index 000000000..e9cfba1b2 --- /dev/null +++ b/src/test/java/com/google/cloud/spanner/jdbc/SingleJarTestApplication.java @@ -0,0 +1,55 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.spanner.jdbc; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; + +/** + * Simple Java application that is used to verify the working of the single-jar-with-dependencies. + */ +public class SingleJarTestApplication { + + public static void main(String[] args) throws Exception { + if (args.length != 3) { + throw new IllegalArgumentException("expected 3 arguments"); + } + String project = args[0]; + String instance = args[1]; + String database = args[2]; + String extraOptions = ""; + String host = ""; + if (System.getenv("SPANNER_EMULATOR_HOST") != null) { + extraOptions = "?autoConfigEmulator=true"; + host = "//" + System.getenv("SPANNER_EMULATOR_HOST"); + } + + try (Connection connection = + DriverManager.getConnection( + String.format( + "jdbc:cloudspanner:%s/projects/%s/instances/%s/databases/%s%s", + host, project, instance, database, extraOptions))) { + try (ResultSet resultSet = + connection.createStatement().executeQuery("select 'Hello World from Real Spanner!'")) { + while (resultSet.next()) { + System.out.println(resultSet.getString(1)); + } + } + } + } +} diff --git a/src/test/java/com/google/cloud/spanner/jdbc/it/ITSingleJarTest.java b/src/test/java/com/google/cloud/spanner/jdbc/it/ITSingleJarTest.java new file mode 100644 index 000000000..9ae8f6003 --- /dev/null +++ b/src/test/java/com/google/cloud/spanner/jdbc/it/ITSingleJarTest.java @@ -0,0 +1,126 @@ +/* + * Copyright 2024 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.cloud.spanner.jdbc.it; + +import static org.junit.Assert.assertEquals; + +import com.google.cloud.spanner.Database; +import com.google.cloud.spanner.DatabaseId; +import com.google.cloud.spanner.ParallelIntegrationTest; +import com.google.common.collect.ImmutableList; +import com.google.common.io.CharStreams; +import java.io.InputStreamReader; +import java.nio.file.Files; +import java.nio.file.Paths; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Tests that the following works: + * + *
    + *
  1. Build a single-jar-with-dependencies + *
  2. Compile a simple Java application consisting of a single file and no dependencies to a + * class file + *
  3. Run the simple Java application with only itself + the single-jar-with-dependencies on the + * class path + *
+ */ +@Category(ParallelIntegrationTest.class) +@RunWith(JUnit4.class) +public class ITSingleJarTest extends ITAbstractJdbcTest { + @ClassRule public static JdbcIntegrationTestEnv env = new JdbcIntegrationTestEnv(); + + private Database database; + + @Before + public void setup() { + database = + env.getOrCreateDatabase( + getDialect(), + ImmutableList.of("create table test (id int64, value string(max)) primary key (id)")); + } + + @Test + public void testUseSingleJar() throws Exception { + buildSingleJar(); + buildMainClass(); + runTestApplication(); + } + + @Test + public void testUseShadedJar() throws Exception { + buildShadedJar(); + buildMainClass(); + runTestApplication(); + } + + private void runTestApplication() throws Exception { + DatabaseId id = database.getId(); + ProcessBuilder builder = new ProcessBuilder(); + if (System.getenv("SPANNER_EMULATOR_HOST") != null) { + builder.environment().put("SPANNER_EMULATOR_HOST", System.getenv("SPANNER_EMULATOR_HOST")); + } + // This runs the simple test application with only the shaded jar on the classpath. + builder.command( + "java", + "-cp", + "./target/single/test/:target/single/single.jar", + "com/google/cloud/spanner/jdbc/SingleJarTestApplication", + id.getInstanceId().getProject(), + id.getInstanceId().getInstance(), + id.getDatabase()); + execute(builder); + } + + private void buildSingleJar() throws Exception { + ProcessBuilder builder = new ProcessBuilder(); + builder.command("mvn", "clean", "package", "-DskipTests", "-Dalt.build.dir=./target/single"); + execute(builder); + } + + private void buildShadedJar() throws Exception { + ProcessBuilder builder = new ProcessBuilder(); + builder.command( + "mvn", "clean", "-Pshade", "package", "-DskipTests", "-Dalt.build.dir=./target/single"); + execute(builder); + } + + private void buildMainClass() throws Exception { + Files.createDirectories(Paths.get("target", "single", "test")); + ProcessBuilder builder = new ProcessBuilder(); + builder.command( + "javac", + "src/test/java/com/google/cloud/spanner/jdbc/SingleJarTestApplication.java", + "-d", + "./target/single/test"); + execute(builder); + } + + private void execute(ProcessBuilder builder) throws Exception { + Process process = builder.start(); + String errors; + try (InputStreamReader reader = new InputStreamReader(process.getErrorStream())) { + errors = CharStreams.toString(reader); + } + assertEquals(errors, 0, process.waitFor()); + } +}