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

Java JNI调用PJSIP加载so库报UnsatisfiedLinkError求助

问题根因

这个报错和JNI语法本身无关,是Linux动态链接器的加载机制导致的:你用System.load()指定绝对路径加载libpjsua2.so时,JVM只会按你给的路径加载这一个文件,后续加载这个库依赖的其他子库时,会走系统默认的动态库搜索规则,不会自动把/usr/local/lib这类目录纳入搜索范围。你手动执行ldd能看到所有依赖路径,是因为你当前shell环境的动态搜索路径配置和JVM运行时的配置不一致,所以递归加载到libpjsip-ua.so.2的时候就会抛出文件不存在的错误。

参考文档
  • PJSIP官方Java绑定(pjsua2 JNI层)的编译、部署说明,直接查看PJSIP源码包内pjsip-apps/src/swig/java路径下的README文档,这是官方维护的全平台(Windows DLL/Linux so/macOS dylib)编译指南,没有第三方内容的错漏。
  • JNI的官方规范直接对应Oracle JDK自带的JNI说明文档,里面明确标注了System.load/System.loadLibrary的搜索逻辑、依赖加载规则,是JNI开发的权威参考。
修复方案
  • 方案1:临时生效(开发调试用)
    启动Java程序前先配置当前终端的动态库搜索路径,执行以下命令:
    export LD_LIBRARY_PATH=/usr/local/lib:/home/sip:$LD_LIBRARY_PATH
    
    配置完成后再执行Java主类即可,这个配置仅对当前终端会话生效。
  • 方案2:永久生效(服务器部署用)
    把PJSIP库所在路径写入系统动态库配置,执行以下命令:
    echo "/usr/local/lib" | sudo tee /etc/ld.so.conf.d/pjsip.conf
    sudo ldconfig
    
    执行完会刷新系统动态链接器缓存,之后所有用户启动Java程序都能正常搜索到PJSIP的依赖库。
  • 方案3:不修改系统配置(应用打包分发用)
    把ldd结果里所有/usr/local/lib路径下的PJSIP相关so文件全部拷贝到/home/sip/目录下,然后在Java代码的static块里按依赖层级从底层到上层依次加载所有库,最后再加载JNI封装层libpjsua2.so,示例代码:
    public class Main {
        static {
            try {
                // 从最底层依赖开始加载
                System.load("/home/sip/libpj.so.2");
                System.load("/home/sip/libpjlib-util.so.2");
                System.load("/home/sip/libpjnath.so.2");
                System.load("/home/sip/libpjmedia.so.2");
                System.load("/home/sip/libpjmedia-audiodev.so.2");
                System.load("/home/sip/libpjmedia-codec.so.2");
                System.load("/home/sip/libsrtp.so.2");
                System.load("/home/sip/libresample.so.2");
                System.load("/home/sip/libspeex.so.2");
                System.load("/home/sip/libwebrtc.so.2");
                System.load("/home/sip/libgsmcodec.so.2");
                System.load("/home/sip/libilbccodec.so.2");
                System.load("/home/sip/libpjsip.so.2");
                System.load("/home/sip/libpjsip-ua.so.2");
                System.load("/home/sip/libpjsip-simple.so.2");
                System.load("/home/sip/libpjsua.so.2");
                // 最后加载JNI适配库
                System.load("/home/sip/libpjsua2.so");
                System.out.println("Loaded");
            } catch (UnsatisfiedLinkError e) {
                System.err.println("Native code library failed to load.\n" + e);
                System.exit(1);
            }
        }
    
        public static void main(String argv[])
        {
            Call call = new Call(null, 0);
            System.out.println("this is call: "+call);
        }
    }
    
注意事项
  • 你代码里加载的libpjsua2.so是SWIG生成的JNI封装层,不是PJSIP核心库,它本身依赖整套PJSIP核心so文件,缺任意一个依赖都会报链接错误。
  • 后续编译Windows平台DLL时逻辑完全一致:要么把所有PJSIP依赖的DLL放到jar包同目录,要么把DLL所在路径加入系统PATH环境变量,要么在Java代码里按依赖顺序手动加载所有DLL,不然一样会抛出找不到依赖的错误。
  • 编译JNI库的时候必须保证Java版本、PJSIP版本、CPU架构(32/64位)和运行环境完全匹配,不然即使路径配置正确,也会报符号找不到、架构不匹配的加载错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 08:27:19