OSGI 无法在运行时通过 JNI 链接到本机方法

Posted

技术标签:

【中文标题】OSGI 无法在运行时通过 JNI 链接到本机方法【英文标题】:OSGI cannot link to native method via JNI at runtime 【发布时间】:2013-05-17 18:07:04 【问题描述】:

我正在尝试使用 OSGI 包中的 DLL 中的方法。 DLL 在 OSGI 中正确加载,但我仍然收到 java unsatisfied link 错误,未找到本机方法!

当仅在 Java 中独立部署(无 OSGI)时,DLL 会被加载并完美运行。

这就是我所做的:

我通过 SWIG 为我的 C++ 编译的 DLL 生成了一个 JNI 桥。 我在调用 swig 时指定了包名。 我在我的 Maven pom.xml xml 元素中声明了 dll 包含,这会生成正确的 Manifest 文件。 DLL 库的加载完成后没有任何错误/警告

真正让我困惑的是dll中的符号似乎找不到:

java.lang.UnsatisfiedLinkError: com.bmw.corona.components.sample.impl.generated.AdasDeconstructorJNI.swig_module_init()V

问题是当它与 OSGI 耦合时,我猜在 OSGI 的 ClassLoader 的某个地方。

dll 中的方法似乎具有正确的签名:

_Java_com_bmw_corona_components_sample_impl_generated_AdasDeconstructorJNI_swig_1module_1init@8

在生成的 SWIG 文件中使用以下原型:

SWIGEXPORT void JNICALL Java_AdasDeconstructorJNI_swig_1module_1init(JNIEnv *jenv, jclass jcls)

我三重确定 Manifest 是否包含 Bundle Native 指令。

我做错了什么?

【问题讨论】:

您非常确定您有一个捆绑本机标头...但不愿意向我们展示它的外观? ;-) 【参考方案1】:

您可能想查阅这篇 wiki 文章:http://wiki.osgi.org/wiki/Dependencies_In_Native_Code

很难从您的描述中看出,但听起来您有 2 个本机库。一个带有 JNI 入口点,另一个带有真正的本机函数。上面的 wiki 文章讨论了从 JNI 本机库到其他本机库的依赖关系。

【讨论】:

我只有一个 DLL 入口点,它是 JNI 入口点。从那里,DLL 符号及其 Java 签名被加载到虚拟机中。 wiki 对理解库加载机制非常有帮助。但是,我在 Windows 上工作,这意味着将查询库加载器缓存并在那里找到 dll。 dll 已加载,但不知何故没有访问内部符号。 (.. 我的意思是从 dll 中的抽象类到 Java 类中的实现的方法调用的签名被加载到 VM 中)。不过我们不要把事情复杂化,原来的入口点是 JNI 入口函数 swig_module_init()。【参考方案2】:

问题是双重的。首先,没有发现这些方法与 Visual Studio 2010 的方法名称修改有关。我添加了一个链接器指令:

#pragma comment(linker, "/EXPORT:__Java_com_bmw_corona_components_sample_impl_AdasDeconstructorJNI_swig_module_init=_Java_com_bmw_corona_components_sample_impl_AdasDeconstructorJNI_swig_1module_1init@8")

所有捆绑包(超过 100 个)启动和运行确实需要一些时间,而且在发布后的前几秒钟我确实收到了 java.lang.NullPointerException: null。之后,一切似乎都运行良好。并且 nullPointerException 消失了..

【讨论】:

以上是关于OSGI 无法在运行时通过 JNI 链接到本机方法的主要内容,如果未能解决你的问题,请参考以下文章

通过 JNI 执行 OpenCV 本机函数的问题

csharp 到 java JNI 移植调用以在 ubuntu 上运行

JNI 通过多个 JNI 调用使 C++ 中的对象保持活动状态

我可以在 Java 中控制 JNI 本机方法调用名称吗?

JNI- java.lang.UnsatisfiedLinkError:找不到本机方法

如何修复无法在 Conda 上加载本机 Tensorflow 运行时