17

示例:我有两个共享对象(同样适用于 .dll)。第一个共享对象来自第三方库,我们称之为 libA.so。我已经用 JNI 封装了其中的一些,并创建了我自己的库 libB.so。现在 libB 依赖于 libA。

当 webstart 时,这两个库都位于一些 webstart 工作区中。我的 java 代码尝试加载 libB。此时系统加载器将尝试加载不在系统库路径中的 libA(java.library.path 对此无济于事)。最终结果是 libB 有一个不满意的链接,无法使用。

我曾尝试在 libB 之前加载 libA,但这仍然不起作用。似乎操作系统想为我做那个加载。除了静态编译之外,我还有什么方法可以完成这项工作?

4

3 回答 3

8

我不确定这是否会以与 webstart 完全相同的方式处理,但在处理一组本机库(在我们的例子中为 dll)时,我们在桌面应用程序中遇到了这种情况。

在 libB 之前加载 libA 应该可以工作,除非其中一个库具有未说明且不在路径中的依赖项。我的理解是,一旦它到达系统 loadLibrary 调用(即 Java 已在其 java.library.path 中找到该库,现在告诉操作系统加载它) - 它完全依赖于操作系统来查找任何依赖库,因为此时正在为进程加载库的是操作系统,而操作系统只知道如何查看系统路径。在 Webstart 应用程序的情况下,这似乎很难设置,但有一种不涉及静态编译的方法。您也许可以调整您的图书馆所在的位置 - 我不确定

如果您使用自定义类加载器,则可以覆盖 loadLibrary 和 findLibrary 以便它可以从类路径中的 jar 中找到您的库,并且如果您还让它知道您的本机库依赖项(即 libB 依赖于 libA 依赖于 libX,然后在加载 libB 时,您可以抓住自己并确保首先加载 libA,并检查该通知并首先加载 libX。然后操作系统不会尝试找到不在您路径中的库。这很笨拙而且有点痛苦,但确保 Java 可以找到它们并以正确的顺序加载它们。

于 2008-08-07T17:53:38.113 回答
5

静态编译被证明是 web 启动多个依赖本机库的唯一方法。

于 2009-01-26T01:47:13.227 回答
1

两个本机库是否都打包到一个签名的jar 中,该 jar 被列为

<nativelib ...> 

在 JNLP 文件中?

于 2008-09-17T06:32:00.773 回答