Java 从通过JNI加载的共享库调用dlopen会使以前加载的符号不可见

Java 从通过JNI加载的共享库调用dlopen会使以前加载的符号不可见,java,java-native-interface,dlopen,Java,Java Native Interface,Dlopen,我有一个Java应用程序,它使用JNI与本机代码交互。本机代码在运行时编译文件,并尝试使用dlopen调用加载此文件。此呼叫失败,我收到一条警告 无法加载库(x):(x)未定义的符号:y 但是,当本机应用程序通过JNI启动JVM并运行相同的代码时,不会发生此错误,它会按预期运行。我怀疑Java正在做一些花哨的事情,导致已经加载的库对于加载了dlopen的库是不可见的 我这样做是为了诊断问题: 使用objdump 已确认使用gdb加载此库(通过eclipse-该库已在模块窗格中列出) 在dlop

我有一个Java应用程序,它使用JNI与本机代码交互。本机代码在运行时编译文件,并尝试使用dlopen调用加载此文件。此呼叫失败,我收到一条警告

无法加载库(x):(x)未定义的符号:y

但是,当本机应用程序通过JNI启动JVM并运行相同的代码时,不会发生此错误,它会按预期运行。我怀疑Java正在做一些花哨的事情,导致已经加载的库对于加载了dlopen的库是不可见的

我这样做是为了诊断问题:

  • 使用
    objdump
  • 已确认使用
    gdb
    加载此库(通过eclipse-该库已在模块窗格中列出)
  • 在dlopen之前打印了LD_LIBRARY_路径,并确认Java通过了它(它确实添加了Java的lib dir,但原始dir仍然存在)
我试图解决这个问题已经有一段时间了,但我不知道发生了什么。特别是当JVM从本机应用程序加载时,它确实可以工作


提前谢谢你

我终于找到了答案。解决方案是重新编译包含符号的共享库,该符号未使用
-Wl,--export-dynamic
链接器标志找到

有趣的是,我自己并没有编写这个共享库,我希望默认编译会添加这个标志,因为使用它的软件需要它才能正常工作


无论哪种方式,它都是一个开源项目,因此我可以使用正确的标志集来编译它

,使用JNI提供的
dlopen
,我从来没有遇到过问题。这是什么操作系统?此
y
符号在哪里定义?您确定JVM正在加载任何包含
y
的库吗?是的,就像我说的,我确认了哪个库符号y是使用
objdump-x | grep y
定义的,并检查了JVM正在使用
gdb
加载它。操作系统是Ubuntu 11.10 64位。我正在运行一个
Java(TM)SE运行时环境(build1.6.0_26-b03)
Java热点(TM)64位服务器虚拟机(build20.1-b02,混合模式)
。我还确认了应该加载的库也是64位的,我认为我的问题与libtool的-export动态标志有关。然而,我尝试设置这个,它似乎并没有解决问题。我会继续尝试。我正在通过
/configure
命令编译
GSL
库。我应该把这个链接器选项放在哪里?你能解释一下你认为这两个标志在做什么吗?