Mac OS X上的JNI重复库加载崩溃

时间:2016-05-09 12:52:05

标签: java java-native-interface shared-libraries static-libraries static-linking

我有两个共享库A.dylib和B.dylib,它们都与静态库S.a

链接

当我只使用System.load或System.loadLibrary加载A.dylib时,没有问题。对于B.dylib也是如此。

但是当我一个接一个地加载(顺序无关紧要)时,我看到第二个加载的库在某些初始化代码上崩溃了。当我检查堆栈时,崩溃的代码块在S.a

不知何故,当A.dylib和B.dylib都被加载时,它们之间共享S.a符号。这只发生在Mac OS X中。堆栈清楚地显示第二个加载的一个通过第一个加载的方法调用S.a的方法。更清楚;

  • 加载A.dylib
  • A#init - >从静态链接的S.a
  • 调用方法
  • 加载B.dylib
  • B#init - >通过A.dylib
  • 调用静态链接的S.a的方法

我尝试在不同的类加载器中加载A.dylib和B.dylib,但这并没有改变结果。你知道是否有办法防止这种分享?

1 个答案:

答案 0 :(得分:0)

我找到了解决方案,

问题是因为我猜测静态库默认情况下会暴露它们的符号,所以最后由于重复符号而存在名称冲突。

在链接动态库时,我将链接器标志-exported_symbols_list设置为一个输入文本文件,该文件仅包含公开的符号。就我而言,这些只是JNI层方法; _Java_package_methodName _JNI_OnLoad _JNI_OnUnload

-exported_symbols_list仅导出输入文件中列出的符号。其余的都是隐藏的,因此我没有重复的符号。

我不知道为什么它不会在Linux和Windows上发生。