在 Mac OS X 上加载 JNI 库?

6

背景

我正在尝试在Mac OS X上运行时将jnilib(特别是JOGL)加载到Java中。我一直在关注相关的Stack Overflow问题:

对于我来说,最终目标是将平台特定的JOGL文件打包到JAR中,解压缩它们到临时目录并在启动时加载它们。我通过硬编码路径来尝试简化我的问题,即尝试加载JOGL:

    File f = new File("/var/folders/+n/+nfb8NHsHiSpEh6AHMCyvE+++TI/-Tmp-/libjogl.jnilib");
    System.load(f.toString());
    f = new File ("/var/folders/+n/+nfb8NHsHiSpEh6AHMCyvE+++TI/-Tmp-/libjogl_awt.jnilib");
    System.load(f.toString());

当我尝试使用JOGL API时,出现以下异常:

    Exception in thread "main" java.lang.UnsatisfiedLinkError: no jogl in java.library.path

但是,当我通过添加以下JVM选项指定java.library.path时:
    -Djava.library.path="/var/folders/+n/+nfb8NHsHiSpEh6AHMCyvE+++TI/-Tmp-/" 

一切运作正常。


问题

在 Mac OS X 上,是否可以使用 System.load(或其他变体)作为在运行时调用的 -Djava.library.path 的替代品?

3个回答

2

在启动时,您不必提供java.library.path。您可以使用编程方式设置它。

System.setProperty("java.library.path", "/var/folder/bla/foo/bar/");

我不知道在没有这个库路径的情况下,System.load() 是否会以某种方式起作用。

1
谢谢您的建议。然而,根据我的经验,在运行时设置“java.library.path”没有任何效果。我认为这可能是类路径无法在运行时更改的原因相似 - https://dev59.com/BHVC5IYBdhLWcg3whBaj - Clinton
然后你可能遇到了一个依赖库的问题。在运行时设置库路径非常完美,我过去就是这样加载我的库的。 - David Sauter
这并不完全正确,有一种方法可以强制使用新的lib.path重新初始化类加载器。 - Zorkus
做类似这样的事情: System.setProperty("java.library.path", newPath);Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths"); fieldSysPath.setAccessible(true); fieldSysPath.set(null, null); - Zorkus

1
Jogl总是尝试自动加载所有依赖库。 为了避免这种情况,应该有一个NativeLibLoader类,在你通过System.load()自己加载库之前,可以调用disableLoading()。

太好了!感谢您,手动加载库之前调用NativeLibLoader.disableLoading()非常成功。 - Clinton

-3

System.load(...) 接受 libraryName 作为参数,而不是路径。

JVM 在 -Djava.library.path 指定的路径列表中搜索指定名称的库,这与 Mac OS X 上的操作方式相同。

这里没有特定于 Mac OS X 的内容。它在所有操作系统上以相同的方式搜索库。


2
那是错误的,实际上 System.load() 会接受完整的文件名,而 System.loadLibrary 则会接受库名称。 - sreejith
我认为加载jnilib是Mac特定的(在我的情况下是这样)。我已经在Linux上使其工作(.so),在Mac上编译后,jnilib不会加载。我使用mvn jetty:deploy-war -Djava.library.path=/path/to/jnilib。我甚至使用了System.setProperty("mylib.systemclassloader", "false");以便它可以在servlet环境中运行(它禁用了该库的自动加载)。可能的原因是什么? - Pramod

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接