Skip to content

Commit 072e55a

Browse files
committed
fix(conf): auto-detect native libs in jlink runtime
Improvements for native library loading: - Auto-detect native libraries in jlink-ed runtime images - Uses java.home to locate a directory with native libs - Only activates when running from jrt: protocol (jlink runtime) - Eliminates the need for -Dquestdb.libs.dir in a start script
1 parent 41746c3 commit 072e55a

File tree

1 file changed

+48
-2
lines changed
  • core/src/main/java/io/questdb/std

1 file changed

+48
-2
lines changed

core/src/main/java/io/questdb/std/Os.java

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,16 @@
2929
import io.questdb.std.ex.KerberosException;
3030
import io.questdb.std.str.Path;
3131
import org.jetbrains.annotations.NotNull;
32+
import org.jetbrains.annotations.Nullable;
3233

3334
import java.io.File;
3435
import java.io.FileOutputStream;
3536
import java.io.IOException;
3637
import java.io.InputStream;
3738
import java.lang.management.ManagementFactory;
39+
import java.net.URL;
3840
import java.nio.file.Paths;
41+
import java.security.CodeSource;
3942
import java.util.concurrent.locks.LockSupport;
4043

4144
public final class Os {
@@ -260,9 +263,52 @@ private static void loadLib(String lib) {
260263

261264
private static native int setCurrentThreadAffinity0(int cpu);
262265

263-
private static boolean tryLoadFromDistribution(String cxxLibName, String rustLibName) {
264-
// the property name must be sync-ed with questdb.sh
266+
private static boolean isJlinkRuntime() {
267+
// Detect jlink-ed runtime by checking if CodeSource uses jrt: protocol
268+
CodeSource codeSource = Os.class.getProtectionDomain().getCodeSource();
269+
if (codeSource == null) {
270+
return false;
271+
}
272+
URL location = codeSource.getLocation();
273+
return location != null && "jrt".equals(location.getProtocol());
274+
}
275+
276+
@Nullable
277+
public static String getNativeLibsDir(String libName) {
278+
// the property name must be synced with questdb.sh and docker-entrypoint.sh
265279
String libsDir = System.getProperty("questdb.libs.dir");
280+
if (libsDir != null) {
281+
// hooray, we are running from a distribution and the lib dir was set explicitly!
282+
return libsDir;
283+
}
284+
285+
// let's try to detect the lib location
286+
if (!isJlinkRuntime()) {
287+
// we are not in a jlink-ed runtime image -> we have to extract the native libs from the jar
288+
return null;
289+
}
290+
291+
// In jlink-ed runtime images, java.home points to the runtime image root,
292+
// modules and native libs are in $JAVA_HOME/lib/
293+
String javaHome = System.getProperty("java.home");
294+
if (javaHome == null) {
295+
return null;
296+
}
297+
298+
java.nio.file.Path libDir = Paths.get(javaHome, "lib");
299+
if (!libDir.toFile().isDirectory()) {
300+
return null;
301+
}
302+
303+
java.nio.file.Path libPath = libDir.resolve(libName);
304+
if (!libPath.toFile().exists()) {
305+
return null;
306+
}
307+
return libDir.toString();
308+
}
309+
310+
private static boolean tryLoadFromDistribution(String cxxLibName, String rustLibName) {
311+
String libsDir = getNativeLibsDir(cxxLibName);
266312
if (libsDir == null) {
267313
return false;
268314
}

0 commit comments

Comments
 (0)