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

Error looking up 'symbolName': e.getMessage()

Error message

Error looking up 'symbolName': e.getMessage()

What it means

NativeLibrary.getGlobalVariableAddress rethrows an UnsatisfiedLinkError from symbol lookup wrapped as "Error looking up '<symbol>': <original message>". It means the named global variable/symbol could not be resolved in the loaded native library.

Source

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

            return function;
        }
    }

    /** @return this native library instance's options. */
    public Map<String, ?> getOptions() {
        return options;
    }

    /** Look up the given global variable within this library.
     * @param symbolName
     * @return Pointer representing the global variable address
     * @throws UnsatisfiedLinkError if the symbol is not found
     */
    public Pointer getGlobalVariableAddress(String symbolName) {
        try {
            return new Pointer(getSymbolAddress(symbolName));
        } catch(UnsatisfiedLinkError e) {
            throw new UnsatisfiedLinkError("Error looking up '" + symbolName + "': " + e.getMessage());
        }
    }

    /**
     * Used by the Function class to locate a symbol
     * @throws UnsatisfiedLinkError if the symbol can't be found
     */
    long getSymbolAddress(String name) {
        if (handle == 0) {
            throw new UnsatisfiedLinkError("Library has been unloaded");
        }
        return this.symbolProvider.getSymbolAddress(handle, name, NATIVE_SYMBOL_PROVIDER);
    }

    @Override
    public String toString() {
        return "Native Library <" + libraryPath + "@" + handle + ">";
    }

View on GitHub (pinned to d036ad9781)

Solutions

  1. Verify the symbol is exported: nm -D libfoo.so | grep symbol (or dumpbin/otool)
  2. Check for C++ name mangling; declare extern "C" in the native code or use the mangled name
  3. Confirm the loaded library version matches the headers you coded against
  4. Read the nested e.getMessage() in the error text for the underlying cause

Example fix

// before
Pointer p = lib.getGlobalVariableAddress("errno_value");
// after
// verify with: nm -D libfoo.so | grep errno
Pointer p = lib.getGlobalVariableAddress("errno"); // actual exported name
Defensive patterns

Strategy: try-catch

Validate before calling

// confirm export beforehand:
// nm -D libfoo.so | grep <symbolName>
if (symbolName == null || symbolName.isEmpty()) throw new IllegalArgumentException("symbolName required");

Try / catch

try {
    Pointer p = lib.getGlobalVariableAddress("mySymbol");
} catch (UnsatisfiedLinkError e) {
    // symbol missing/mangled; parse e.getMessage() for the inner cause
}

Prevention

When it happens

Trigger: Calling lib.getGlobalVariableAddress("symbol") where the symbol does not exist, the library was loaded but exports it under a different (e.g. mangled or versioned) name, or the symbol is in a dependency library.

Common situations: Typo in symbol name; symbol only exported with C++ name mangling; using headers from a different library version than the loaded binary; static library symbols stripped by the linker.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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