我如何Java Webstart多个依赖的本机库?
示例:我有两个共享对象(对.dll应该相同)。第一个共享库来自第三方库,我们将其称为libA.so。我已经用JNI封装了其中的一些内容,并创建了自己的库libB.so。现在,libB取决于libA。
网络启动时,两个库都位于某些网络启动工作区中。我的Java代码尝试加载libB。此时,系统加载器将尝试加载不在系统库路径中的libA(java.library.path对此无济于事)。最终结果是libB的链接不满意,无法使用。
我曾尝试在libB之前加载libA,但这仍然无法正常工作。似乎操作系统要为我执行该加载。除了静态编译之外,还有什么方法可以使这项工作有效?
解决方案
回答
我不确定是否可以使用完全相同的方式来处理Webstart,但是在处理一组本机库(在本例中为dll)时,我们在桌面应用程序中遇到了这种情况。
在libB之前加载libA应该可以工作,除非其中一个库具有无法解释的依赖关系,并且不在路径中。我的理解是,一旦它进入系统loadLibrary调用(即Java在其java.library.path中找到了该库,现在正在告诉OS对其进行加载),它完全依赖于操作系统来查找任何依赖的库,因为在那时,是操作系统为进程加载了库,而OS只知道如何在系统路径中查找。对于Webstart应用程序,这似乎很难设置,但是有一种解决方法不涉及静态编译。我们不确定我的图书馆可能在哪里洗牌
如果我们使用自定义的类加载器,则可以覆盖loadLibrary和findLibrary,以便它可以从类路径中的jar中找到库,并且还使它知道本机库依赖项(即libB依赖libA依赖libX然后在加载libB时,我们会陷入困境并确保先加载libA,然后在检查该通知时先加载libX,然后操作系统不会尝试查找不在路径中的库。这很笨拙,有点痛苦,但可以确保Java找到它们并以正确的顺序加载它们。
回答
是否将两个本机库都打包到一个签名的jar中,列为
<nativelib ...>
在JNLP文件中?
回答
事实证明,静态编译是Webstart多个依赖本机库的唯一方法。