我正在调用一些试图加载Java类的C ++代码,例如
JNIEnv *jenv = ...
jclass cls = jenv->FindClass("org/some/bundle/SomeClass");
现在,问题是这个类驻留在一个OSGi包中,上面的代码找不到我的类。
此问题仅在运行单元测试时出现(Tycho-surefire无头测试)。有没有一种简单的方法可以强制OSGi框架从JNI中找到我的类?在Java方面,我怀疑像Dynamic-ImportPackage
这样的东西可以解决我的问题。我不愿意改变第三方C ++库以使其与测试框架一起工作,所以如果可能的话,我更喜欢Java测试设置/配置方面的解决方案。
JNIEnv的FindClass方法仅搜索由全局应用程序类路径定义的系统ClassLoader的内容。由于OSGi不使用全局类路径,因此这不起作用也就不足为奇了。
通常,每当加载一个类时,您不仅需要指定类名,还需要指定应加载它的类加载器。这是模块化的必然要求。因此,您的代码需要能够找到您希望包含该类的包,然后调用其loadClass方法。您可以直接在C ++代码中执行此操作,但编写Java实用程序方法来执行此操作然后从C ++调用该方法可能更容易。
好吧,我不是百分百肯定你的情况就像我的一样。
在我的RCP中我曾经得到例外:
com.tool.packageB_1.0.0.qualifier找不到ClassNotFoundException:com.tool.packageA.IWantToLoadThisClass
一个简单的解决方案是:
我想避免这个解决方案,因为我能够加载其他包中的其他类,通常是com.tool.packageC,com.tool.packageD(这不是我做的,所以我不知道它是如何工作的)。
在我周围搜索时,我找到了另一种解决方案,我最终使用它来保持与当前工作包类似的东西(com.tool.packageC,com.tool.packageD)。
解决方案是:
这是如何让它工作:
Eclipse-BuddyPolicy: registered
添加到com.tool.packageB MANIFEST.MFEclipse-RegisterBuddy: com.tool.packageB
添加到com.tool.packageA MANIFEST.MFRequire-Bundle: com.tool.packageB
添加到com.tool.packageA MANIFEST.MF现在从com.tool.packageB可以看到com.tool.packageA.IWantToLoadThisClass,你可以在jenv->FindClass("com/tool/packageA/IWantToLoadThisClass");
找到它。
我希望这有帮助。