You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android JNI库适配Java SE遇UnsatisfiedLinkError,CMake构建失败求助

解决Java SE环境下JNI原生库构建与加载问题

错误原因

你碰到的UnsatisfiedLinkError核心是Java找不到对应的原生共享库——Android的Gradle插件会自动触发CMake构建流程,但标准Java SE的Gradle项目默认不会执行这一步,导致没有生成可供Java加载的库文件。

解决方案:两种方式实现构建与集成

方式一:手动用CMake构建原生库

先手动编译出Java SE兼容的共享库,再让Java加载:

  1. 创建并进入构建目录:
    mkdir build && cd build
    
  2. 执行CMake配置(不同平台可按需调整,比如Windows需指定生成器):
    # macOS/Linux
    cmake .. -DCMAKE_BUILD_TYPE=Release
    # Windows示例(用VS2022生成器)
    cmake .. -G "Visual Studio 17 2022" -DCMAKE_BUILD_TYPE=Release
    
  3. 编译生成库文件:
    # macOS/Linux
    make -j4
    # Windows
    cmake --build . --config Release
    
  4. 找到编译后的库:
    • macOS:libutilities_whitebox.dylib
    • Linux:libutilities_whitebox.so
    • Windows:utilities_whitebox.dll
  5. 让Java定位到库:
    • 方法1:把库文件放到错误提示里的java.library.path路径(比如当前目录.)
    • 方法2:启动Java时指定库路径:
      java -Djava.library.path=/你的库文件目录 MainClass
      

方式二:用Gradle自动触发CMake构建

如果想通过Gradle统一管理Java编译和原生库构建,可在构建脚本中添加自定义任务:

Groovy版build.gradle配置

plugins {
    id 'java'
}

// 定义CMake构建任务
task buildNative(type: Exec) {
    def buildDir = file("$projectDir/build/native")
    buildDir.mkdirs()

    // 执行CMake配置
    commandLine 'cmake', '..', '-DCMAKE_BUILD_TYPE=Release', "-B$buildDir"
    workingDir buildDir.parentFile

    // 执行编译
    doLast {
        commandLine 'cmake', '--build', buildDir.path, '--config', 'Release'
    }
}

// 让Java编译任务依赖原生构建任务
compileJava.dependsOn buildNative

// 配置Java运行时的库路径
run {
    systemProperty 'java.library.path', "$projectDir/build/native"
}

Kotlin版build.gradle.kts配置

plugins {
    java
}

// 定义CMake构建任务
tasks.register<Exec>("buildNative") {
    val buildDir = file("$projectDir/build/native")
    buildDir.mkdirs()

    // CMake配置命令
    commandLine("cmake", "..", "-DCMAKE_BUILD_TYPE=Release", "-B$buildDir")
    workingDir = buildDir.parentFile

    // 编译命令
    doLast {
        commandLine("cmake", "--build", buildDir.path, "--config", "Release")
    }
}

// 让Java编译依赖原生构建
tasks.compileJava {
    dependsOn(tasks.named("buildNative"))
}

// 配置运行时库路径
tasks.run {
    systemProperty("java.library.path", "$projectDir/build/native")
}

额外注意点

  • 检查JNI桥接代码(SwigWbc_wrap.cpp)是否兼容Java SE:如果代码里用到了Android专属JNI API(比如AndroidLog相关),需要替换成Java SE的实现。
  • 不同平台的库文件格式不同,跨平台使用需分别编译对应版本。

内容的提问来源于stack exchange,提问作者Oyebisi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 18:52:35