必须安装含javac的jdk而非jre,且需gcc/clang支持动态库编译;ndk仅用于android开发;system.loadlibrary、jni函数命名和头文件签名三者必须严格一致,否则报unsatisfiedlinkerror。

必须装 JDK(不是 JRE)且确认 javac 和 java 可用
OpenJDK 是基础,但光有 java 命令不够——javac 编译器和 javah(JDK 10 前)或 -h 参数(JDK 10+)必须可用,否则无法生成 JNI 头文件。很多系统默认只装 JRE,比如 Ubuntu 的 openjdk-17-jre 就不含 javac。
验证方式很简单:
java -version<br>javac -version
如果第二行报 “command not found”,就得重装带编译器的包,例如:
- Ubuntu/Debian:
sudo apt install openjdk-17-jdk(不是-jre) - macOS(Homebrew):
brew install openjdk@17,然后手动把$(brew --prefix openjdk@17)/bin加进PATH - Windows:下载 OpenJDK x64 Compressed Archive,解压后设
JAVA_HOME指向根目录,并把%JAVA_HOME%in加入PATH
gcc 或 clang 必须能编译出动态库
JNI 最终要生成 .so(Linux)、.dylib(macOS)或 .dll(Windows),这就要求本地有 C/C++ 编译器,且支持生成共享库。
常见错误是只装了 gcc 却没装 g++(C++ 支持),或者没加 -fPIC 和 -shared 标志,导致链接失败或 JVM 加载时报 UnsatisfiedLinkError。
编译命令典型结构(以 Linux 为例):
gcc -fPIC -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/linux" -shared -o libhello.so hello.c
注意点:
-
-I路径必须准确:不同 OpenJDK 版本的include子目录名可能不同(如linux、darwin、win32) - macOS 需用
-dynamiclib替代-shared,输出扩展名是.dylib - Windows 下若用 MinGW,命令中路径分隔符要用
\,且头文件路径含win32
NDK 不是必需的,除非你开发 Android
很多人混淆“JNI”和“Android NDK”。纯 Java 桌面或服务器端 JNI 开发,完全不需要 Android NDK——它只在 Android 平台构建 .so 时才用。NDK 提供的是交叉编译链(如 aarch64-linux-android-clang),而桌面开发直接用本机 gcc 或 clang 即可。
如果你只是写一个 HelloWorld.java + hello.c 在 Linux/macOS/Windows 上跑,装好 OpenJDK 和本机编译器就足够了。NDK 反而会引入架构错配(比如编译出 arm64 的 so 却在 x86_64 JVM 上加载)。
只有当你明确目标是 Android APK 时,才需要:
- Android Studio 中启用 NDK(r21e 及以上)
- 在
build.gradle里配置ndkVersion和abiFilters - 用 CMake 或
ndk-build管理原生代码
容易被忽略的细节:头文件路径、符号命名、库名匹配
即使工具都齐了,UnsatisfiedLinkError 仍高频出现,根本原因往往不是环境没配好,而是这三点不一致:
-
System.loadLibrary("xxx")中的"xxx"必须和生成的库文件名前缀一致:Linux 上是libxxx.so,Windows 是xxx.dll,macOS 是libxxx.dylib - C 函数名必须严格遵循 JNI 命名规范:
Java_包名_类名_方法名,中间下划线不能少,大小写不能错,包名中的.要换成_ - 调用
javac -h . HelloWorld.java生成的hello.h里声明的函数签名,必须和 C 实现里的函数签名(参数类型、返回值)完全一致;尤其注意jstring、jintArray这类 JNI 类型,不能直接当char*或int*用
这些地方一错,JVM 在解析 native 方法时就找不到对应符号,报错信息里常带 XXX.V 或 XXX.J 这种字节码签名,说明符号表对不上——这时候别急着重装工具,先用 nm -D libxxx.so | grep Java(Linux/macOS)检查导出符号是否真的存在且拼写正确。











