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