如何使用 Java Web 启动多个依赖的本机库?
示例:我有两个共享对象(同样适用于 .dll)。 第一个共享对象来自第三方库,我们将其称为 libA.so。 我用 JNI 包装了其中的一些内容并创建了我自己的库 libB.so。 现在 libB 依赖于 libA。
当网络启动时,这两个库都位于某个网络启动工作区域中。 我的 java 代码尝试加载 libB。 此时系统加载器将尝试加载不在系统库路径中的libA(java.library.path对此无济于事)。 最终结果是libB有一个不满足的链接,无法使用。
我尝试在 libB 之前加载 libA,但这仍然不起作用。 似乎操作系统想为我加载。 除了静态编译之外,还有什么方法可以使其工作吗?
Example: I have two shared objects (same should apply to .dlls). The first shared object is from a third-party library, we'll call it libA.so. I have wrapped some of this with JNI and created my own library, libB.so. Now libB depends on libA.
When webstarting, both libraries are places in some webstart working area. My java code attempts to load libB. At this point the system loader will attempt to load libA which is not in the system library path (java.library.path won't help this). The end result is that libB has an unsatisfied link and cannot be used.
I have tried loading libA before libB, but that still does not work. Seems the OS wants to do that loading for me. Is there any way I can make this work other than statically compiling?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
静态编译被证明是 webstart 多个依赖的本机库的唯一方法。
Static compilation proved to be the only way to webstart multiple dependent native libraries.
列出?
这两个本机库是否都打包到一个签名 jar 中,并在 JNLP 文件中
Are both native libraries packaged into a signed jar which is listed as
In the JNLP file?
我不确定这是否会以与 Webstart 完全相同的方式处理,但在处理一组本机库(在我们的例子中为 dll)时,我们在桌面应用程序中遇到了这种情况。
在 libB 之前加载 libA 应该可以工作,除非这些库之一具有未说明且不在路径中的依赖项。 我的理解是,一旦它到达系统 loadLibrary 调用(即 Java 在其 java.library.path 中找到了该库,现在告诉操作系统加载它) - 它完全依赖于操作系统来查找任何依赖库,因为此时操作系统正在为进程加载库,并且操作系统只知道如何在系统路径中查找。 对于 Webstart 应用程序来说,这似乎很难设置,但是有一种不涉及静态编译的方法可以解决这个问题。 您也许可以调整您的库的位置 - 我不确定
如果您使用自定义类加载器,您可以覆盖 loadLibrary 和 findLibrary,以便它可以从类路径中的 jar 中找到您的库,并且如果您还让它知道您的本机库依赖项(即 libB 依赖于 libA 依赖于 libX,然后在加载 libB 时您可以捕获自己并确保首先加载 libA,并在检查通知时首先加载 libX。然后操作系统不会尝试查找库这并不在你的路径中,这很笨重并且有点痛苦,但是确保 Java 找到它们并以正确的顺序加载它们是可行的。
I'm not sure if this would be handled exactly the same way for webstart, but we ran into this situation in a desktop application when dealing with a set of native libraries (dlls in our case).
Loading libA before libB should work, unless one of those libraries has a dependency that is unaccounted for and not in the path. My understanding is that once it gets to a system loadLibrary call (i.e. Java has found the library in its java.library.path and is now telling the OS to load it) - it is completely dependent on the operating system to find any dependent libraries, because at that point it is the operating system that is loading the library for the process, and the OS only knows how to look in the system path. That seems hard to set in the case of a Webstart app, but there is a way around this that does not involve static compiling. You may be able to shuffle where your libraries are - I am unsure
If you use a custom classloader, you can override loadLibrary and findLibrary so that it can locate your libraries from within a jar in your classpath, and if you also make it aware of your native library dependencies (i.e. libB depends on libA depends on libX, then when loading libB you can catch yourself and ensure you load libA first, and in checking that notice and load libX first. Then the OS doesn't try to find a library that isn't in your path. It's klunky and a bit painful, but ensuring Java finds them and loads them all in the correct order can work.