运行Java文件出现java.lang.UnsatisfiedLinkError: JNIExample.getVersion错误如何解决
报错复现
执行启动命令:
D:\JNIExample\JNIExample\JNIExample>java JNIExample
触发异常:
Exception in thread "main" java.lang.UnsatisfiedLinkError: JNIExample.getVersion([B[I)I at JNIExample.getVersion(Native Method) at JNIExample.main(JNIExample.java:15)
错误产生原因
- 签名不匹配:Java侧声明的
getVersionnative方法和C/C++侧实现的JNI函数签名不一致,包括方法名、参数类型、返回值类型任意一项不匹配都会触发该错误。报错中[B[I)I是方法签名,分别对应byte数组参数、int数组参数、int返回值,C侧实现如果和该签名不符就会报错。 - 动态链接库未加载/加载失败:Java代码没有调用
System.loadLibrary()或System.load()加载包含native方法实现的dll文件,或者加载的dll路径错误、JVM位数和dll位数不匹配,导致JVM找不到对应实现。 - JNI函数未正确导出:C/C++侧实现的方法没有加
JNIEXPORT和JNICALL修饰符,或者编译dll时没有导出对应的函数符号,JVM无法定位到实现逻辑。 - 类全限定名不匹配:如果Java侧
JNIExample类带有包名,C侧的JNI函数名没有对应加上包名的下划线分隔前缀,也会出现匹配失败。
修复方案
- 自动生成JNI头文件,避免手动写签名错误:在源码目录下执行命令
javac -h . JNIExample.java,会自动生成包含正确函数签名的头文件,C/C++侧直接引用该头文件实现方法即可,不要手动拼写函数名。 - 确认动态库正确加载:在调用
getVersion方法之前添加库加载代码,Windows下示例:
同时确认dll的位数和你运行用的JVM位数一致,32位dll只能在32位JVM上运行,64位同理。// 加载同目录下的JNIExample.dll System.loadLibrary("JNIExample"); // 路径不对的话可以直接写绝对路径 // System.load("D:\\JNIExample\\JNIExample.dll"); - 检查JNI函数导出符号:C/C++侧的实现必须带
JNIEXPORT和JNICALL修饰,示例正确实现格式:
编译完dll后可以用JNIEXPORT jint JNICALL Java_JNIExample_getVersion(JNIEnv *env, jobject obj, jbyteArray arg1, jintArray arg2) { // 你的实现逻辑 }dumpbin /exports JNIExample.dll命令查看导出符号,确认包含上述函数名。 - 确认类全限定名匹配:如果
JNIExample类有包名,比如包为com.test,则C侧函数名需要改为Java_com_test_JNIExample_getVersion,运行时不要随意修改类的包名或类名。
内容的提问来源于stack exchange,提问作者Dildar
相关产品推荐
相关产品推荐

