【发布时间】:2018-12-08 10:38:44
【问题描述】:
将导出的 Java 项目从开发机器移到生产机器后,我遇到了麻烦。
java项目(一个Eclipse插件)有一个我写的JNI库,它依赖于一个开源库,而开源库又依赖于Boost。我在我的 SLES11 机器上编译了包括 Boost 在内的所有内容,程序运行正常。
当我将程序移动到另一台机器上时,我得到了错误:
java.lang.UnsatisfiedLinkError:/path/to/project/lib/libMyJNI.so: libboost_system.so.1.67.0: cannot open shared object file: No such file or directory
我在同一目录中复制了所需的库。
ldd libMyJNI.so 列出了 20 个依赖项,但都解决了所有问题。
我仍然遇到同样的错误。
我假设java.library.path 设置正确,因为它会尝试加载libMyJNI.so 并识别依赖关系。
如果 ldd 有效,我是否正确地期望 java 应该解决依赖关系?
有什么线索吗?
谢谢!
编辑:这是 ldd ldd libMyJNI.so 的输出
linux-vdso.so.1 => (0x00007fffa59ff000)
libboost_system.so.1.67.0 (0x00007fc427bce000)
libboost_filesystem.so.1.67.0 (0x00007fc4279b4000)
libboost_thread.so.1.67.0 (0x00007fc42778f000)
libboost_date_time.so.1.67.0 (0x00007fc42757a000)
libboost_iostreams.so.1.67.0 (0x00007fc42735f000)
libboost_serialization.so.1.67.0 (0x00007fc42710f000)
libboost_chrono.so.1.67.0 (0x00007fc426f06000)
libboost_atomic.so.1.67.0 (0x00007fc426d04000)
libboost_regex.so.1.67.0 (0x00007fc426a00000)
libpcl_common.so.1.8 (0x00007fc42673b000)
libpcl_io.so.1.8 (0x00007fc4263cb000)
libpcl_octree.so.1.8 (0x00007fc425fdc000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007fc425c98000)
libm.so.6 => /lib64/libm.so.6 (0x00007fc425a42000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fc42582b000)
libc.so.6 => /lib64/libc.so.6 (0x00007fc4254cc000)
librt.so.1 => /lib64/librt.so.1 (0x00007fc4252c3000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fc4250a6000)
libz.so.1 => /lib64/libz.so.1 (0x00007fc424e8f000)
libgomp.so.1 => /usr/lib64/libgomp.so.1 (0x00007fc424c86000)
libpcl_io_ply.so.1.8 (0x00007fc424a21000)
libpng12.so.0 => /usr/lib64/libpng12.so.0 (0x00007fc4247f9000)
/lib64/ld-linux-x86-64.so.2 (0x00007fc427fe8000)
【问题讨论】:
-
ldd列表提升了吗?可能它毕竟没有联系。链接器不会抱怨,因为在 Linux 中假定所有需要的库都将链接到可执行文件中。 JNI 库并非如此。 -
@user2543253 是的,它列出了一些 boost 库、一些来自开源库的库以及诸如
libm.so、libc.so之类的东西。完全没看懂,怎么链接? -
嗯,但它是否列出了错误消息所抱怨的确切文件?那里有那个确切的文件吗?它可读吗?
-
您是使用不同的用户还是使用 sudo 运行程序,这样它可能会获得与
ldd不同的环境?我对ldd输出有点困惑。我从未见过它列出了没有=>和路径的库。 -
没有 JNI 链接器之类的东西。你说你想加载一个库,Java 让操作系统加载器为你加载它。 “java.library.path”也只与实际的 JNI lib 有关。操作系统看不到它的依赖关系,也不会关心它。
ld.so.conf和LD_LIBRARY_PATH通常是唯一需要检查的内容。但是,您可以在 Java 中加载一个非 JNI 库,操作系统应该在解决依赖关系时找到它,因为它已经在内存中。也许您可以尝试从代码中加载“问题”库,看看是否会收到更有用的错误消息。
标签: java boost java-native-interface sles