{"record":{"id":"a43acc39366042e6","repo":"tursodatabase/turso","slug":"unable-to-load-necessary-native-library","errorCode":null,"errorMessage":"Unable to load necessary native library","messagePattern":"Unable to load necessary native library","errorType":"exception","errorClass":"InternalError","httpStatus":null,"severity":"critical","filePath":"bindings/java/src/main/java/tech/turso/core/TursoDB.java","lineNumber":110,"sourceCode":"  /**\n   * This method attempts to load the native library required for turso operations. It first tries\n   * to load the library from the system's library path using {@link #loadFromSystemPath()}. If that\n   * fails, it attempts to load the library from the JAR file using {@link #loadFromJar()}. If\n   * either method succeeds, the `isLoaded` flag is set to true. If both methods fail, an {@link\n   * InternalError} is thrown indicating that the necessary native library could not be loaded.\n   *\n   * @throws InternalError if the native library cannot be loaded from either the system path or the\n   *     JAR file.\n   */\n  private static void load() {\n    new SingletonHolder();\n  }\n\n  // \"lazy initialization holder class idiom\" (Effective Java #83)\n  private static class SingletonHolder {\n    static {\n      if (!loadFromSystemPath() && !loadFromJar()) {\n        throw new InternalError(\"Unable to load necessary native library\");\n      }\n    }\n  }\n\n  /**\n   * Load the native library from the system path.\n   *\n   * <p>This method attempts to load the native library named \"_turso_java\" from the system's\n   * library path. If the library is successfully loaded, the `isLoaded` flag is set to true.\n   *\n   * @return true if the library was successfully loaded, false otherwise.\n   */\n  private static boolean loadFromSystemPath() {\n    try {\n      System.loadLibrary(\"_turso_java\");\n      return true;\n    } catch (Throwable t) {\n      logger.info(\"Unable to load from default path: {}\", String.valueOf(t));","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/tursodatabase/turso/blob/bad083fafbefdeae9a42ec19bdaaad8918dcf411/bindings/java/src/main/java/tech/turso/core/TursoDB.java#L92-L128","documentation":"The SingletonHolder static initializer tries System.loadLibrary(\"_turso_java\") first, then extracts and loads the JAR-bundled library. If both fail it throws InternalError. Because detect() returning UNSUPPORTED, a missing libs/ resource, an unwritable temp dir (convertInputStreamToFile), or System.load failures all land in the same catch, the logger lines 'Unable to load from default path:' and 'Unable to load from jar:' carry the real cause.","triggerScenarios":"First TursoDB.create(...) on: an OS/arch where detect() returns UNSUPPORTED (riscv64, ppc64le, ...); a JAR whose libs/ native resources were stripped by shading/repackaging; a read-only or noexec java.io.tmpdir; a bundled .so whose system dependencies (glibc) are missing, e.g. on Alpine/musl.","commonSituations":"Maven shade/Gradle shadow jars silently dropping libs/** resources; hardened Docker images with noexec TMPDIR; Alpine Linux lacking glibc; SNAPSHOT artifacts published without native classifiers; corrupt artifact downloads.","solutions":["Read the two logger.info lines — they name the exact underlying failure from both load attempts","Verify the JAR actually contains libs/<os>_<arch>/lib_turso_java.* ; if shading stripped it, depend on the unshaded artifact or add the native resource to the shade filter","Build the native library from source and load it via -Djava.library.path so loadFromSystemPath() succeeds","Point -Djava.io.tmpdir at a writable, exec-mounted directory","On Alpine, switch to a glibc-based image or build the library natively for musl"],"exampleFix":"# before: shaded jar lost libs/ resources, temp dir noexec\njava -jar app.jar   # InternalError: Unable to load necessary native library\n\n# after: writable+exec tmp dir, explicit system-path fallback\njava -Djava.io.tmpdir=/var/tmp/jni -Djava.library.path=/opt/turso-native -jar app.jar","handlingStrategy":"fallback","validationCode":"// fail fast before first use, with the real cause surfaced\nString libPath = \"/libs/\" + (isLinux() ? \"linux_x86/lib_turso_java.so\" : \"\");\nboolean bundled = TursoDB.class.getResourceAsStream(libPath) != null;\nboolean onSystemPath = System.getProperty(\"java.library.path\") != null;\nif (!bundled && !onSystemPath) {\n  throw new IllegalStateException(\"turso native library missing: no bundled \" + libPath);\n}","typeGuard":null,"tryCatchPattern":"try {\n  Connection c = DriverManager.getConnection(url);\n} catch (Throwable t) {\n  if (t instanceof InternalError || t instanceof ExceptionInInitializerError) {\n    // log the two 'Unable to load from ...' logger lines; they carry the root cause.\n    // fall back: provision lib_turso_java via -Djava.library.path and restart\n  }\n}","preventionTips":["Smoke-test one connection at application start so load failures surface at boot, not mid-request","When shading, keep libs/** resources in the fat jar (configure the shade filter)","Ensure java.io.tmpdir is writable and exec-mounted; prefer glibc-based base images"],"tags":["java","native-library","jni","classpath","bindings","docker"],"backgroundTag":"native-library-load-failure","analyzedSha":"bad083fafbefdeae9a42ec19bdaaad8918dcf411","analyzedAt":"2026-08-16T23:12:11.798Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}