java-native-access/jna · critical · java.lang.UnsatisfiedLinkError

Failed to load library 'libraryName'

Error message

Failed to load library 'libraryName'

What it means

NativeLibrary.getInstance throws UnsatisfiedLinkError when Native.open cannot load the shared library at the resolved path. The error is collected into a list of attempts because JNA may retry alternate search strategies (e.g. Android preloading) before giving up.

Source

Thrown at src/com/sun/jna/NativeLibrary.java:228

        //
        try {
            LOG.log(DEBUG_LOAD_LEVEL, "Trying " + libraryPath);
            handle = Native.open(libraryPath, openFlags);
        } catch(UnsatisfiedLinkError e) {
            // Add the system paths back for all fallback searching
            LOG.log(DEBUG_LOAD_LEVEL, "Loading failed with message: " + e.getMessage());
            LOG.log(DEBUG_LOAD_LEVEL, "Adding system paths: " + librarySearchPath);
            exceptions.add(e);
            searchPath.addAll(librarySearchPath);
        }

        try {
            if (handle == 0) {
                libraryPath = findLibraryPath(libraryName, searchPath);
                LOG.log(DEBUG_LOAD_LEVEL, "Trying " + libraryPath);
                handle = Native.open(libraryPath, openFlags);
                if (handle == 0) {
                    throw new UnsatisfiedLinkError("Failed to load library '" + libraryName + "'");
                }
            }
        } catch(UnsatisfiedLinkError ule) {
            LOG.log(DEBUG_LOAD_LEVEL, "Loading failed with message: " + ule.getMessage());
            exceptions.add(ule);
            // For android, try to "preload" the library using
            // System.loadLibrary(), which looks into the private /data/data
            // path, not found in any properties
            if (Platform.isAndroid()) {
                try {
                    LOG.log(DEBUG_LOAD_LEVEL, "Preload (via System.loadLibrary) " + libraryName);
                    System.loadLibrary(libraryName);
                    handle = Native.open(libraryPath, openFlags);
                }
                catch(UnsatisfiedLinkError e2) {
                    LOG.log(DEBUG_LOAD_LEVEL, "Loading failed with message: " + e2.getMessage());
                    exceptions.add(e2);
                }

View on GitHub (pinned to d036ad9781)

Solutions

  1. Verify the library file exists at the resolved path (check java.library.path and jna.library.path)
  2. Set jna.library.path or LD_LIBRARY_PATH to the directory containing the library
  3. Check file architecture matches the JVM (file libfoo.so shows x86-64 vs aarch64 etc.)
  4. Install missing transitive dependencies with ldd/otool/Dependencies.exe
  5. On Android, ensure the .so is packaged under jniLibs/<abi>/
  6. Read the full list of accumulated UnsatisfiedLinkErrors; JNA keeps every failed attempt

Example fix

// before
NativeLibrary.getInstance("mylib");
// after
System.setProperty("jna.library.path", "/opt/myapp/lib");
NativeLibrary lib = NativeLibrary.getInstance("mylib");
Defensive patterns

Strategy: try-catch

Validate before calling

String path = NativeLibrary.processUtil.getLibc...; // or verify manually:
java.io.File lib = new java.io.File(System.getProperty("java.library.path").replace(':', java.io.File.pathSeparatorChar).split(java.io.File.pathSeparatorChar)[0], "libmylib.so");
if (!lib.exists()) {
    System.setProperty("jna.library.path", "/opt/myapp/lib");
}

Try / catch

try {
    NativeLibrary lib = NativeLibrary.getInstance("mylib");
} catch (UnsatisfiedLinkError e) {
    // check jna.library.path, architecture, dependencies
    throw new RuntimeException("Native library mylib failed to load: " + e.getMessage(), e);
}

Prevention

When it happens

Trigger: Calling NativeLibrary.getInstance("name") where findLibraryPath returns a path that Native.open fails to load: missing .so/.dll/.dylib file, wrong architecture (32/64-bit), missing transitive dependencies, or bad permissions.

Common situations: Native library not on java.library.path; missing system dependencies (e.g. libstdc++); cross-compiled binary mismatched with OS/arch; Android APK not packaging the .so; LD_LIBRARY_PATH not set.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12). Data as JSON: /api/errors/19b8b4334262353c. Report an issue: GitHub.