diff --git a/x-pack/plugin/sql/sql-client/src/main/java/org/elasticsearch/xpack/sql/client/Version.java b/x-pack/plugin/sql/sql-client/src/main/java/org/elasticsearch/xpack/sql/client/Version.java index 3f7134272c9c5..dd217011081e0 100644 --- a/x-pack/plugin/sql/sql-client/src/main/java/org/elasticsearch/xpack/sql/client/Version.java +++ b/x-pack/plugin/sql/sql-client/src/main/java/org/elasticsearch/xpack/sql/client/Version.java @@ -85,14 +85,16 @@ static byte[] from(String ver) { // This is similar to how Elasticsearch's Build class digs up its build information. // Since version info is not critical, the parsing is lenient - URL url = Version.class.getProtectionDomain().getCodeSource().getLocation(); - String urlStr = url.toString(); + CURRENT = extractVersion(Version.class.getProtectionDomain().getCodeSource().getLocation()); + } + static Version extractVersion(URL url) { + String urlStr = url.toString(); byte maj = 0, min = 0, rev = 0; String ver = "Unknown"; String hash = ver; - if (urlStr.endsWith(".jar")) { + if (urlStr.endsWith(".jar") || urlStr.endsWith(".jar!/")) { try (JarInputStream jar = new JarInputStream(url.openStream())) { Manifest manifest = jar.getManifest(); hash = manifest.getMainAttributes().getValue("Change"); @@ -105,7 +107,7 @@ static byte[] from(String ver) { throw new IllegalArgumentException("Detected Elasticsearch JDBC jar but cannot retrieve its version", ex); } } - CURRENT = new Version(ver, hash, maj, min, rev); + return new Version(ver, hash, maj, min, rev); } @Override diff --git a/x-pack/plugin/sql/sql-client/src/test/java/org/elasticsearch/xpack/sql/client/VersionTests.java b/x-pack/plugin/sql/sql-client/src/test/java/org/elasticsearch/xpack/sql/client/VersionTests.java index 7ed772e352531..ce3b18e591bae 100644 --- a/x-pack/plugin/sql/sql-client/src/test/java/org/elasticsearch/xpack/sql/client/VersionTests.java +++ b/x-pack/plugin/sql/sql-client/src/test/java/org/elasticsearch/xpack/sql/client/VersionTests.java @@ -6,7 +6,17 @@ package org.elasticsearch.xpack.sql.client; import org.elasticsearch.test.ESTestCase; -import org.elasticsearch.xpack.sql.client.Version; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.util.jar.Attributes; +import java.util.jar.JarEntry; +import java.util.jar.JarOutputStream; +import java.util.jar.Manifest; public class VersionTests extends ESTestCase { public void test70Version() { @@ -43,4 +53,42 @@ public void testInvalidVersion() { IllegalArgumentException err = expectThrows(IllegalArgumentException.class, () -> Version.from("7.1")); assertEquals("Invalid version 7.1", err.getMessage()); } + + public void testVersionFromJarInJar() throws IOException { + Path dir = createTempDir(); + Path jarPath = dir.resolve("foo.jar"); + Path innerJarPath = dir.resolve("es-sql-jdbc.jar"); + + Manifest jdbcJarManifest = new Manifest(); + Attributes attributes = jdbcJarManifest.getMainAttributes(); + attributes.put(Attributes.Name.MANIFEST_VERSION, "1.0.0"); + attributes.put(new Attributes.Name("Change"), "abc"); + attributes.put(new Attributes.Name("X-Compile-Elasticsearch-Version"), "1.2.3"); + + try (JarOutputStream jdbc = new JarOutputStream(Files.newOutputStream(innerJarPath, StandardOpenOption.CREATE), jdbcJarManifest)) {} + + try (BufferedInputStream in = new BufferedInputStream(Files.newInputStream(innerJarPath)); + JarOutputStream out = new JarOutputStream(Files.newOutputStream(jarPath, StandardOpenOption.CREATE), new Manifest())) { + JarEntry entry = new JarEntry("es-sql-jdbc.jar!/"); + out.putNextEntry(entry); + + byte[] buffer = new byte[1024]; + while (true) { + int count = in.read(buffer); + if (count == -1) { + break; + } + out.write(buffer, 0, count); + } + } + + URL jarInJar = new URL("jar:" + jarPath.toUri().toURL().toString() + "!/es-sql-jdbc.jar!/"); + + Version version = Version.extractVersion(jarInJar); + assertEquals(1, version.major); + assertEquals(2, version.minor); + assertEquals(3, version.revision); + assertEquals("abc", version.hash); + assertEquals("1.2.3", version.version); + } }