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

ARM架构Mac加载libfingerprints.dylib遇UnsatisfiedLinkError求助

ARM架构Mac下Java加载第二个动态库失败的非常规排查方案

问题描述

运行以下Java代码时,第一个动态库加载正常,但第二个库始终加载失败:

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello world!");
        System.load("/Users/orlando/libbinaryen.dylib");
        System.load("/Users/orlando/libfingerprints.dylib");
    }
}

执行输出:

Hello world!
Exception in thread "main" java.lang.UnsatisfiedLinkError: Can't load library: /Users/orlando/libfingerprints.dylib
    at java.base/java.lang.ClassLoader.loadLibrary(ClassLoader.java:2393)
    at java.base/java.lang.Runtime.load0(Runtime.java:755)
    at java.base/java.lang.System.load(System.java:1953)
    at Main.main(Main.java:9)

已尝试过自行编译的库、他人在ARM Mac上编译且可正常运行的库,均无法解决。同时已确认文件权限、路径、处理器架构匹配,使用java -Djava.library.path=/Users/orlando/Git/lib -verbose:jni -classpath /Users/orlando/Git/HelloWorld/out/production/HelloWorld Main调试,输出仍显示相同错误。

额外验证信息

# 库架构验证
>> file libfingerprints.dylib
libfingerprints.dylib: Mach-O 64-bit dynamically linked shared library arm64

# 库依赖检查
>> otool -L libfingerprints.dylib
libfingerprints.dylib:
  @rpath/libfingerprints.dylib (compatibility version 0.0.0, current version 0.0.0)
  /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 1500.65.0)
  /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1319.100.3)

# 系统架构
>> uname -m
arm64

# Java版本
>> java --version
openjdk version "17.0.4.1" 2022-08-12 LTS
OpenJDK Runtime Environment Corretto-17.0.4.9.1 (build 17.0.4.1+9-LTS)
OpenJDK 64-Bit Server VM Corretto-17.0.4.9.1 (build 17.0.4.1+9-LTS, mixed mode, sharing)

非常规排查方向与验证方法

  • 用系统工具直接加载库,排除Java层面问题
    写个简单的C程序调用dlopen加载库,看系统动态链接器能否正常加载:

    // test_dlopen.c
    #include <dlfcn.h>
    #include <stdio.h>
    
    int main() {
        void* handle = dlopen("/Users/orlando/libfingerprints.dylib", RTLD_NOW);
        if (!handle) {
            fprintf(stderr, "dlopen failed: %s\n", dlerror());
            return 1;
        }
        printf("Library loaded successfully\n");
        dlclose(handle);
        return 0;
    }
    

    编译运行:

    clang test_dlopen.c -o test_dlopen && ./test_dlopen
    

    如果这里也失败,问题出在系统层面,和Java无关;如果成功,再聚焦Java加载逻辑。

  • 追踪动态库加载的完整依赖链
    用DYLD_PRINT_LIBRARIES环境变量打印加载过程的详细日志,看动态链接器寻找依赖时的行为:

    # 先在C测试程序中追踪
    DYLD_PRINT_LIBRARIES=1 ./test_dlopen
    # 再在Java进程中追踪
    DYLD_PRINT_LIBRARIES=1 java -classpath /Users/orlando/Git/HelloWorld/out/production/HelloWorld Main
    

    重点看加载libfingerprints.dylib时,是否有依赖找不到、版本不匹配的情况。

  • 检查Java进程的环境变量与系统权限限制
    查看Java进程的环境变量,确认DYLD相关路径是否被修改:

    java -classpath /Users/orlando/Git/HelloWorld/out/production/HelloWorld -XshowSettings:properties Main | grep dyld
    

    另外检查系统完整性保护(SIP)状态,SIP可能限制某些路径的库加载:

    csrutil status
    

    若SIP开启,可临时关闭测试(测试后务必恢复):

    # 重启进入恢复模式后执行
    csrutil disable
    # 测试完成后重启恢复模式执行
    csrutil enable
    
  • 验证库的代码签名与公证状态
    ARM Mac对代码签名要求更严格,检查库的签名:

    codesign -vvv /Users/orlando/libfingerprints.dylib
    

    如果签名无效,尝试重新签名:

    codesign -f -s - /Users/orlando/libfingerprints.dylib
    

    注意:自签名库在SIP开启时可能仍无法加载,需用开发者证书签名或添加到系统允许列表。

  • 排查两个库之间的符号/依赖冲突
    尝试单独加载libfingerprints.dylib,不加载libbinaryen.dylib,看是否能成功:

    public class Main {
        public static void main(String[] args) {
            System.out.println("Hello world!");
            System.load("/Users/orlando/libfingerprints.dylib");
        }
    }
    

    如果单独加载成功,说明两个库存在冲突,用nm导出符号对比:

    nm -gU /Users/orlando/libbinaryen.dylib > binaryen_syms.txt
    nm -gU /Users/orlando/libfingerprints.dylib > fingerprints_syms.txt
    comm -12 binaryen_syms.txt fingerprints_syms.txt
    

    输出的内容就是两个库共有的导出符号,可能存在冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 00:17:39