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 链接到本机方法的主要内容,如果未能解决你的问题,请参考以下文章
csharp 到 java JNI 移植调用以在 ubuntu 上运行
JNI 通过多个 JNI 调用使 C++ 中的对象保持活动状态