系统loadLibrary不工作。链中第二个库的未满足链接错误

 2023-01-20    293  

问题描述

我有Java程序client.class使用CPP共享库libclient.so通过JNI.
libclient.so是作为共享构建的,并使用cpp共享库libhttp.so.

libclient.so和libhttp.so放在文件夹/home/client/lib64中

client.class放置在/home/client/bin

系统loadLibrary不工作。链中第二个库的未满足链接错误

客户端可以加载库

  1. 系统.负载和环境变量ld_library_path
  2. system.loadlibrary和-djava.library.path

第一种方法正常工作.

export LD_LIBRARY_PATH = /home/client/lib64

java -classpath ./bin客户端

secon方法失败.

java -classpath ./bin -Djava.library.path=./../lib64 Client

java.lang.UnsatisfiedLinkError: /home/client/lib64/libclient.so: libhttp.so: cannot open shared object file: No such file or directory

当我将libhttp.so放入/usr/lib64时,第二种方法正常工作.

为什么如果我使用system.loadlibrary?
我如何在不应对libhttp.so中进行修复,以/usr/lib64?

我的加载代码:

//Try load from -Djava.library.path        
    boolean found = false;
    String lib = "client";
    try {
       System.loadLibrary(lib);
       found = true;
    } catch (UnsatisfiedLinkError e) {
       e.printStackTrace();
    }
    //Try load from LD_LIBRARY_PATH
    if (!found) {
       lib = "libclient.so";
       String ld_lib_path = System.getenv("LD_LIBRARY_PATH");
       String[] paths = ld_lib_path.split(":");
       for(int i=0; i<paths.length; i++) {
          String p = paths[i];
          File x = new File(p, lib);
          if (x.exists()) {
             System.load(x.getAbsolutePath());
             found = true;
             break;
          }
       }
    }

其他信息.

如果我测试了libclient.so用ldd,我会看到:libhttp.so =>找不到
如果我设置了导出ld_library_path =/home/client/lib64,则我会看到:libhttp.so =>/home/client/lib64/libhttp.so

推荐答案

这样做的原因是libclient.so是从您的JVM加载的,它看起来java.library.path.但是,当libclient.so尝试加载libhttp. C7>.

我可能会从Java应用程序的启动脚本中使用LD_LIBRARY_PATH设置.如果您不想使用start脚本,则可以从过程本身中从理论上设置LD_LIBRARY_PATH.但是,Java不允许这样做(只有System.getenv(),而不是System.setenv()),因此您需要编写一个从Java调用并调用 putenv() 设置LD_LIBRARY_PATH.

如果您构建libclient.so本身,则可以使用-rpath链接器标志来指定动态链接器应寻找进一步必需库的路径.请注意,如果您在此处指定相对路径,则将其解释为相对于运行应用程序的当前工作目录,而不是相对于libclient.so的位置.为了实现这一目标,您需要使用$ORIGIN作为-rpath的参数,请小心您的外壳不会扩展.

因此,如果您想在同一目录中具有libclient.so和libhttp.so,则需要使用

-rpath '$ORIGIN'

在构建libclient.so时作为链接器的参数.如果您不直接调用链接器,但请让您的编译器调用,则需要将以下内容添加到编译器的命令行中:

-Wl,-rpath,'$ORIGIN'

有关此此信息的更多信息,请参见 Man Page for ld.so .

其他推荐答案

我对这个问题没有好的答案.

但是我找到了几种不错的方法.

  1. 将libhttp.so放入库的共享位置,例如/usr/lib64.
  2. 将通往libhttp.so的路径放入ld_library_path.
  3. 用libhttp.so构建libclient.so so inceent.
  4. 在建立libclient时使用-FRATH.

其他推荐答案

用于库的正确查找(来自 java.library.path ),用于不同的OS,必须具有不同的名称:

  • linux: libhttp.so
  • Windows: http.dll

您可以从Java打电话:

System.loadLibrary( "http" );

以上所述是小编给大家介绍的系统loadLibrary不工作。链中第二个库的未满足链接错误,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!

原文链接:https://77isp.com/post/26199.html

=========================================

https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。