从JNI加载OSGi类

时间:2013-06-07 08:35:49

标签: java-native-interface osgi eclipse-rcp tycho

我正在调用一些试图加载Java类的C ++代码,例如

JNIEnv *jenv = ...
jclass cls = jenv->FindClass("org/some/bundle/SomeClass");

现在,问题是这个类驻留在一个OSGi包中,上面的代码找不到我的类。

此问题仅在运行单元测试时出现(Tycho-surefire无头测试)。有没有一种简单的方法可以强制OSGi框架从JNI中找到我的类?在Java方面,我怀疑像Dynamic-ImportPackage这样的东西可以解决我的问题。我不愿意改变第三方C ++库以使其与测试框架一起工作,所以如果可能的话,我更喜欢Java测试设置/配置方面的解决方案。

2 个答案:

答案 0 :(得分:4)

JNIEnv的FindClass方法仅搜索由全局应用程序类路径定义的系统ClassLoader的内容。由于OSGi不使用全局类路径,所以毫无疑问这不起作用。

通常在加载类时,您不仅需要指定类名,还需要指定应加载它的类加载器。这是模块化的必然要求。因此,您的代码需要能够找到您希望包含该类的包,然后调用其loadClass方法。您可以直接在C ++代码中执行此操作,但是编写Java实用程序方法来执行此操作然后从C ++调用该方法可能更容易。

答案 1 :(得分:1)

好吧,我不是100%确定您的案件像我的案件。

在我的RCP中,我曾经得到异常:

  

ClassNotFoundException:com.tool.packageB_1.0.0.qualifier找不到com.tool.packageA.IWantToLoadThisClass


一个简单的解决方案是:

  • com.tool.packageA 添加到 com.tool.packageB MANIFEST.MF Require-Bundle。

我虽然想避免该解决方案,因为我能够加载通常在其他软件包中找到的其他类 com.tool.packageC,com.tool.packageD (这不是我做的但是我不知道它是如何工作的。)


四处寻找,我找到了另一个解决方案,我最终使用该解决方案来保持与当前工作包( com.tool.packageC,com.tool.packageD )相似的内容。

解决方案是:

这是使其工作的方式:

  1. Eclipse-BuddyPolicy: registered添加到 com.tool.packageB MANIFEST.MF
  2. Eclipse-RegisterBuddy: com.tool.packageB添加到 com.tool.packageA MANIFEST.MF
  3. Require-Bundle: com.tool.packageB添加到 com.tool.packageA MANIFEST.MF

现在 com.tool.packageB 中将显示 com.tool.packageA.IWantToLoadThisClass ,您将可以在jenv->FindClass("com/tool/packageA/IWantToLoadThisClass");时找到它。< / p>

我希望这会有所帮助。