System.loadLibrary 不起作用。链中第二个库的 UnsatisfiedLinkError

2023-11-26

我有java程序Client.class,它通过JNI使用cpp共享库libclient.so。 libclient.so 构建为共享并使用 cpp 共享库 libhttp.so。

libclient.so 和 libhttp.so 放在文件夹中/home/client/lib64
Client.class 放置在/home/client/bin

客户端无法加载库

  1. System.load和环境变量LD_LIBRARY_PATH
  2. System.loadLibrary 和 -Djava.library.path

第一种方法效果很好。

export LD_LIBRARY_PATH = /home/client/lib64

java -classpath ./bin 客户端

第二种方法失败了。

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,为什么 libclient.so 会在 /usr/lib64 中查找 libhttp.so? 如何在不将 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;
          }
       }
    }

附加信息。

如果我用 ldd 测试 libclient.so 然后我会看到: libhttp.so => not found 如果我设置 export LD_LIBRARY_PATH = /home/client/lib64 那么我会看到: libhttp.so => /home/client/lib64/libhttp.so


原因是 libclient.so 是从 JVM 加载的,它会查找java.library.path。然而,当 libclient.so 尝试加载 libhttp.so 时,它对 Java 一无所知,只是使用加载共享库的常规 Linux 方式(动态链接器ld.so),它看起来在LD_LIBRARY_PATH和一些常见的目录,例如/usr/lib64.

我可能会选择使用LD_LIBRARY_PATH从 Java 应用程序的启动脚本中设置。如果您不想使用启动脚本,理论上您可以设置LD_LIBRARY_PATH从流程本身内部。然而,Java不允许这样做(只有System.getenv(), not System.setenv()),因此您需要编写一个从 Java 调用的小型 C 库,并调用putenv()环境LD_LIBRARY_PATH.

如果你建造libclient.so本身,您可以使用-rpath链接器标志指定动态链接器应在其中查找更多所需库的路径。请注意,如果您在此处指定相对路径,它将被解释为相对于正在运行的应用程序的当前工作目录,而不是相对于libclient.so。为了实现这一点,您需要使用$ORIGIN作为论据-rpath并小心你的 shell 不会扩展它。

所以,如果你想拥有libclient.so and libhttp.so在同一目录中,您需要使用

-rpath '$ORIGIN'

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

-Wl,-rpath,'$ORIGIN'

有关这方面的更多信息可以在手册页ld.so.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

System.loadLibrary 不起作用。链中第二个库的 UnsatisfiedLinkError 的相关文章

随机推荐

  • jQuery mobile:在 ListView 中启用自动换行

    我有一个列表视图 见下图 我想将所有内容自动换行 而不是添加 到长行 这是怎么做到的 您只需要更新 CSS ui li desc保存列表项中文本的元素 ui page ui content ui listview ui li desc wh
  • QtService 应用程序作为服务运行时无法连接到系统总线

    我已经重新编译了Qt与集成的dbus对于窗户 此外 我还实施了QtService应用程序在系统总线上注册服务和对象 如下所示 QDBusConnection systemBus registerService com mycompany C
  • 从 R 中的许多列中减去数据框中的一列

    我有一个数据框 我想从所有其他列中减去第二列 我可以循环执行此操作 但我想在一次调用中执行此操作 这是我的工作循环代码 df lt data frame x 100 101 y 2 3 z 3 4 a 1 0 b 4 5 for i in
  • 如何使用 PDO 在一个数据库行程中插入多条记录?

    我有一张桌子叫propAmenities其中包含两列amenity id and property id基本上该表保存外键 现在我必须使用以下语句的命名占位符生成 PDO 查询 INSERT INTO propAmenities ameni
  • 计算sql查询中的持续时间总和

    我有一个表 其中有两列开始时间和结束时间 我能够计算每行的持续时间 但我也想获得总持续时间 这个怎么做 Thanks 您的列的数据类型为 TIMESTAMP 如下所示 SQL gt create table mytable start ti
  • 数据聚合 mongodb vs mysql

    我目前正在研究用于具有严格数据聚合要求的项目的后端 项目主要要求如下 为每个用户存储数百万条记录 用户每年可能拥有超过 100 万个条目 因此即使有 100 个用户 我们每年也会有 1 亿个条目 这些条目的数据聚合必须即时执行 用户需要能够
  • 无法从 List 转换为 List

    我正在尝试传递一个列表DerivedClass一个函数 它接受一个列表BaseClass 但我收到错误 cannot convert from System Collections Generic List
  • React.js Material-UI 中的 BottomNavigation 样式

    如何将所选链接 本例中为主页 的图标和文本颜色更改为红色 并将非活动链接 本例中为课程和作者 的图标和文本颜色更改为绿色 文档非常薄 class MyBottomNavigation extends Component render ret
  • scipy.linalg.solve (LAPACK gesv) 在大矩阵上的时间复杂度?

    如果我使用scipy linalg solve 我相信这称为 LAPACK 的 gesv 函数 在我的工作站上解决约 12000 个未知问题 具有约 12000 个平方 密集 非对称矩阵 时 我得到了一个很好的答案10 15分钟 只是为了探
  • sql表中的树形视图

    我有如下所示的 sql 表 我必须在树视图中显示它 id parentid name 1 NULL outlook 2 1 overcast 3 1 rainy 4 1 sunny 5 2 yes 6 3 wind 7 4 humidity
  • 在 django Forms 中定义 css 类

    假设我有一个表格 class SampleClass forms Form name forms CharField max length 30 age forms IntegerField django hacker forms Bool
  • 为什么 Jupyter 显示图表两次?

    我将从 Jupiter 开始分析一些销售数据 它有效 但每次我绘制图表时 图表都会显示两次 我的笔记本中的前两个图表是在班级内绘制的 对于这些图表来说 这种情况不会发生 注意 Model这里指的是产品的模型 而不是预测模型 class Mo
  • UIStepper - 找出它是递增还是递减

    确定在 UIStepper 中是否按下了加号或减号按钮我使用以下方法 void stepperOneChanged UIStepper stepperOne 而我比较stepperOne value全局值保存在我的 TableView 类中
  • 如何使用 Knife 编辑 ec2 节点的 Chef 属性

    我想使用编辑 ec2 节点的 node dataknife node命令 我可以使用以下命令手动执行此操作 knife node edit NODE NAME它将生成一个我需要编辑的 json name NODE 1 3 chef envi
  • matplotlib - 从等高线提取数据

    我想从均匀间隔的二维数据 类似图像的数据 的单个轮廓中获取数据 基于类似问题中发现的示例 如何获取等高线图 matplotlib 绘制的线的 x y 值 gt gt gt import matplotlib pyplot as plt gt
  • Anaconda Python:删除 pkgs 中的 .tar.gz

    删除 tar gz文件会有问题吗C Users username AppData Local conda pkgs 我还看到同一 Python 包的 Python 子目录 但版本不同 例如 pandas 0 19 2 np111py27 1
  • Tensorflow 无法识别 cudart64_101.dll

    我的路径中有一个DLL文件 C Program Files NVIDIA GPU Computing Toolkit CUDA v10 1 bin cudart64 101 dll but TensorFlow似乎不认识它 2020 03
  • Maven 多模块:将公共依赖项聚合在一个模块中?

    我搜索了这样的问题但没有找到任何东西 所以我就在这里 我有一个多模块 Maven 项目 多个模块都继承同一个父模块 其中定义了共同的依赖关系 其中 有一个我自己的模块 一个 通用 模块 其中实现了一些通用功能 我的问题是 对于常见依赖项 更
  • 如何显示字节数组十六进制值?

    您好 我正在 c 中制作应用程序 我有包含十六进制值的字节数组 我想将这些值写入文件中 而不将其转换为字符串或其他任何内容 请帮助我 提前致谢 我来晚了一点 但没人提到比特转换器为你带来一点魔力的课程 public static strin
  • System.loadLibrary 不起作用。链中第二个库的 UnsatisfiedLinkError

    我有java程序Client class 它通过JNI使用cpp共享库libclient so libclient so 构建为共享并使用 cpp 共享库 libhttp so libclient so 和 libhttp so 放在文件夹