我正在尝试在Mac OS X 10.10.5上用Java加载本机库,如下所示:
Exception in thread "main" java.lang.UnsatisfiedLinkError: /Users/nyholku/sgCoreTest/libSgCore_wrap.dylib: dlopen(/Users/nyholku/sgCoreTest/libSgCore_wrap.dylib, 1): Library not loaded: @executable_path/../Frameworks/libsgCore64.dylib
并抛出异常:
@executable_path
所以我的问题是otool -L /Users/nyholku/sgCoreTest/libSgCore_wrap.dylib
/Users/nyholku/sgCoreTest/libSgCore_wrap.dylib:
libSgCore_wrap.dylib (compatibility version 0.0.0, current version 0.0.0)
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 104.1.0)
@executable_path/../Frameworks/libsgCore64.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1213.0.0)
指向Java程序的位置,这取决于我从命令行或Eclipse中运行的天气吗?
此外,假设正确的位置是“系统中的某个位置”,比如说'/ Library',在具有嵌入式JVM的可分发Mac OS捆绑包(.app)中处理此问题的最佳策略是什么?
这是我的otool为所涉及的两个库(libsgCore_wrap.dylib中的函数在libsgCore64.dylib中调用函数)所显示的内容:
tool -L /Users/nyholku/sgCoreTest/libsgCore64.dylib
/Users/nyholku/sgCoreTest/libsgCore64.dylib:
@executable_path/../Frameworks/libsgCore64.dylib (compatibility version 1.0.0, current version 1.0.0)
/System/Library/Frameworks/Carbon.framework/Versions/A/Carbon (compatibility version 2.0.0, current version 157.0.0)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 855.14.0)
和
的otool输出{{1}}
作为一个额外的问题,为什么libSgCore_wrap.dylib引用自身以及它到库的位置是什么意思/影响?
答案 0 :(得分:0)
似乎您将.dylib
从其他应用程序直接复制到您的用户文件夹,然后您尝试使用Java加载它。
问题是这些库上的引用使用的@executable_path
是相对于主可执行文件(另一个应用程序)的,当Java尝试加载这些库时,使用@executable_path
的引用不正确,因此dlopen
无法找到所需的依赖项。
针对您的具体情况的可能解决方案是使用@loader_path
,因为此变量与引用二进制文件相关。
因此,如果您只需要这两个库,并且可以使用它们的副本而不必担心它们的更新等,并且两者都在同一目录中,那么您可以尝试复制库并更改它们的引用使用@executable_path
@loader_path
到install_name_tool
。{/ p>
正如您在代码中显示的那样,我认为这两个库位于同一路径/Users/nyholku/sgCoreTest/
,并且由于您使用的是System.loadLibrary
方法,因此您正确设置-Djava.library.path=/Users/nyholku/sgCoreTest/
。
首先,在您的情况下,使用以下命令libSgCore_wrap.dylib
将libsgCore64.dylib
更改为install_name_tool -change oldReference newReference dylibToChange
:
install_name_tool -change @executable_path/../Frameworks/libsgCore64.dylib @loader_path/libsgCore64.dylib libSgCore_wrap.dylib
然后,在您的情况下,您必须使用libsgCore64.dylib
更改install_name_tool -id newReference dylibToChange
的标识符:
install_name_tool -id @loader_path/libsgCore64.dylib libsgCore64.dylib
现在您可以使用这些已修改的库,它们将在Java中正确加载。