Skip to content

Commit f54889a

Browse files
committed
SQL: Handle uberjar scenario where the ES jdbc driver file is bundled in another jar (elastic#51856)
(cherry picked from commit 6247b07)
1 parent 16afbf9 commit f54889a

File tree

2 files changed

+75
-13
lines changed
  • x-pack/plugin/sql/sql-client/src

2 files changed

+75
-13
lines changed

x-pack/plugin/sql/sql-client/src/main/java/org/elasticsearch/xpack/sql/client/Version.java

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import java.io.IOException;
99
import java.net.URL;
10+
import java.net.URLConnection;
1011
import java.util.Collections;
1112
import java.util.Enumeration;
1213
import java.util.LinkedHashSet;
@@ -86,26 +87,34 @@ static byte[] from(String ver) {
8687
// This is similar to how Elasticsearch's Build class digs up its build information.
8788
// Since version info is not critical, the parsing is lenient
8889
URL url = Version.class.getProtectionDomain().getCodeSource().getLocation();
89-
String urlStr = url.toString();
90+
CURRENT = extractVersion(url);
91+
}
9092

93+
static Version extractVersion(URL url) {
94+
String urlStr = url.toString();
9195
byte maj = 0, min = 0, rev = 0;
9296
String ver = "Unknown";
9397
String hash = ver;
94-
95-
if (urlStr.endsWith(".jar")) {
96-
try (JarInputStream jar = new JarInputStream(url.openStream())) {
97-
Manifest manifest = jar.getManifest();
98-
hash = manifest.getMainAttributes().getValue("Change");
99-
ver = manifest.getMainAttributes().getValue("X-Compile-Elasticsearch-Version");
100-
byte[] vers = from(ver);
101-
maj = vers[0];
102-
min = vers[1];
103-
rev = vers[2];
98+
99+
if (urlStr.endsWith(".jar") || urlStr.endsWith(".jar!/")) {
100+
try {
101+
URLConnection conn = url.openConnection();
102+
conn.setUseCaches(false);
103+
104+
try (JarInputStream jar = new JarInputStream(conn.getInputStream())) {
105+
Manifest manifest = jar.getManifest();
106+
hash = manifest.getMainAttributes().getValue("Change");
107+
ver = manifest.getMainAttributes().getValue("X-Compile-Elasticsearch-Version");
108+
byte[] vers = from(ver);
109+
maj = vers[0];
110+
min = vers[1];
111+
rev = vers[2];
112+
}
104113
} catch (Exception ex) {
105114
throw new IllegalArgumentException("Detected Elasticsearch JDBC jar but cannot retrieve its version", ex);
106115
}
107116
}
108-
CURRENT = new Version(ver, hash, maj, min, rev);
117+
return new Version(ver, hash, maj, min, rev);
109118
}
110119

111120
@Override

x-pack/plugin/sql/sql-client/src/test/java/org/elasticsearch/xpack/sql/client/VersionTests.java

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,17 @@
66
package org.elasticsearch.xpack.sql.client;
77

88
import org.elasticsearch.test.ESTestCase;
9-
import org.elasticsearch.xpack.sql.client.Version;
9+
10+
import java.io.BufferedInputStream;
11+
import java.io.IOException;
12+
import java.net.URL;
13+
import java.nio.file.Files;
14+
import java.nio.file.Path;
15+
import java.nio.file.StandardOpenOption;
16+
import java.util.jar.Attributes;
17+
import java.util.jar.JarEntry;
18+
import java.util.jar.JarOutputStream;
19+
import java.util.jar.Manifest;
1020

1121
public class VersionTests extends ESTestCase {
1222
public void test70Version() {
@@ -43,4 +53,47 @@ public void testInvalidVersion() {
4353
IllegalArgumentException err = expectThrows(IllegalArgumentException.class, () -> Version.from("7.1"));
4454
assertEquals("Invalid version 7.1", err.getMessage());
4555
}
56+
57+
public void testVersionFromJarInJar() throws IOException {
58+
final String JDBC_JAR_NAME = "es-sql-jdbc.jar";
59+
final String JAR_PATH_SEPARATOR = "!/";
60+
61+
Path dir = createTempDir();
62+
Path jarPath = dir.resolve("uberjar.jar"); // simulated uberjar containing the jdbc driver
63+
Path innerJarPath = dir.resolve(JDBC_JAR_NAME); // simulated ES JDBC driver file
64+
65+
Manifest jdbcJarManifest = new Manifest();
66+
Attributes attributes = jdbcJarManifest.getMainAttributes();
67+
attributes.put(Attributes.Name.MANIFEST_VERSION, "1.0.0");
68+
attributes.put(new Attributes.Name("Change"), "abc");
69+
attributes.put(new Attributes.Name("X-Compile-Elasticsearch-Version"), "1.2.3");
70+
71+
// create the jdbc driver file
72+
try (JarOutputStream jdbc = new JarOutputStream(Files.newOutputStream(innerJarPath, StandardOpenOption.CREATE), jdbcJarManifest)) {}
73+
74+
// create the uberjar and embed the jdbc driver one into it
75+
try (BufferedInputStream in = new BufferedInputStream(Files.newInputStream(innerJarPath));
76+
JarOutputStream out = new JarOutputStream(Files.newOutputStream(jarPath, StandardOpenOption.CREATE), new Manifest())) {
77+
JarEntry entry = new JarEntry(JDBC_JAR_NAME + JAR_PATH_SEPARATOR);
78+
out.putNextEntry(entry);
79+
80+
byte[] buffer = new byte[1024];
81+
while (true) {
82+
int count = in.read(buffer);
83+
if (count == -1) {
84+
break;
85+
}
86+
out.write(buffer, 0, count);
87+
}
88+
}
89+
90+
URL jarInJar = new URL("jar:" + jarPath.toUri().toURL().toString() + JAR_PATH_SEPARATOR + JDBC_JAR_NAME + JAR_PATH_SEPARATOR);
91+
92+
Version version = Version.extractVersion(jarInJar);
93+
assertEquals(1, version.major);
94+
assertEquals(2, version.minor);
95+
assertEquals(3, version.revision);
96+
assertEquals("abc", version.hash);
97+
assertEquals("1.2.3", version.version);
98+
}
4699
}

0 commit comments

Comments
 (0)