JNI/JNA出现UnsatisfiedLinkError但符号已存在问题求助
Hey there, let's break down why you're hitting that UnsatisfiedLinkError and fix it step by step.
First, let's interpret the output from your objdump command:
0000000000104d50 g F .text 000000000000000e Java_ExtClass_setProperty
0000000000104be0 g F .text 000000000000016a Java_com_company_ExtClass_setProperty
These are JNI-compliant exported functions, not plain C functions. Their naming follows JNI's strict convention: Java_<package_path_with_underscores>_<className>_<methodName>. That's why trying to call a generic setProperty method directly (either via JNI or JNA) fails—your code isn't matching the exact expected name/structure.
Fix 1: Use Native JNI (Match the JNI Naming Convention)
If you want to use standard JNI, your Java class structure must perfectly align with the exported function names:
For Java_com_company_ExtClass_setProperty:
- Create a Java class with the exact package and class name:
package com.company; public class ExtClass { static { // Load the library (automatically resolves libext.so on Linux) System.loadLibrary("ext"); } // Declare the native method with matching name and parameter types // Note: The JNI function's actual parameters are (JNIEnv*, jobject, ...) // So your Java method parameters should map to the remaining arguments public native void setProperty(String key, String value); }
- Ensure your native method's parameter types match what the underlying JNI function expects (e.g.,
jstringin C maps toStringin Java,jintmaps toint, etc.). - When you call
new ExtClass().setProperty("foo", "bar"), JNI will automatically resolve theJava_com_company_ExtClass_setPropertyfunction because your class/package/method name exactly matches the exported name.
For Java_ExtClass_setProperty:
If you want to use this function instead, your Java class should be in the default package (no package declaration) with the name ExtClass, and the same native method signature.
Fix 2: Use JNA (Work Around the JNI Naming)
Since JNA defaults to looking for plain C function names, you need to explicitly reference the full JNI-style exported names:
Option A: Directly Reference the JNI Function Name
Define your JNA interface with the exact exported function name, and account for the mandatory JNI parameters (JNIEnv* and jobject):
import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.Pointer; public interface ExtLibrary extends Library { ExtLibrary INSTANCE = Native.load("ext", ExtLibrary.class); // Call the default-package version void Java_ExtClass_setProperty(Pointer env, Pointer obj, String key, String value); // Or call the com.company version void Java_com_company_ExtClass_setProperty(Pointer env, Pointer obj, String key, String value); }
When calling, you can pass null for env and obj if you don't need JNI context (though some functions may require valid pointers—test carefully).
Option B: Use JNA's JNI Helper Classes (More Robust)
If you need proper JNI context, you can use JNA's JNI class to get a valid JNIEnv pointer, then pass it to the function. This is useful if the native function relies on JNI functionality:
import com.sun.jna.Native; import com.sun.jna.platform.JNI; public class JnaJniCaller { public static void main(String[] args) { JNI jni = JNI.getInstance(); JNI.JNIEnv env = jni.GetEnv(); ExtLibrary.INSTANCE.Java_com_company_ExtClass_setProperty(env.getPointer(), null, "key", "value"); } }
Quick Troubleshooting Checks
- Double-check that your library path is correct (you said loading works, so this is likely fine, but confirm with
System.getProperty("java.library.path")). - Verify case sensitivity: JNI/JNA function names are case-sensitive, so
Java_ExtClass_setPropertyis not the same asjava_extclass_setproperty. - Ensure your Java method parameters exactly match the native function's expected types (mismatches can also trigger
UnsatisfiedLinkErrorin some cases).
内容的提问来源于stack exchange,提问作者billdoor

