【问题标题】:Load OSGi class from JNI从 JNI 加载 OSGi 类
【发布时间】:2013-06-07 08:35:48
【问题描述】:

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

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

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

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

【问题讨论】:

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


    【解决方案1】:

    JNIEnv 的 FindClass 方法只搜索全局应用程序类路径定义的系统 ClassLoader 的内容。由于 OSGi 不使用全局类路径,因此这不起作用也就不足为奇了。

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

    【讨论】:

    • 我理解,它证实了我的假设。问题是,我可以通过简单的重新配置以某种方式解决这个问题,而不更改 C++ 库(我无法直接控制)吗?
    • 例如,我尝试将“org.osgi.framework.system.packages.extra”设置为C++代码加载的类的包,但没有帮助。
    • 并非如此。正如我所说,JNIEnv 读取全局应用程序类路径。可以通过从系统包中导出类路径类来使它们在 OSGi 包中可见......这就是 org.osgi.framework.system.packages.extra 设置所实现的。但是你需要的是另一个方向:从 OSGi Bundle 导入到系统包中,这是不可能的。我能想到的唯一方法是将类移动到全局类路径中,然后从那里导出。
    • 好的,谢谢。你写的东西完全有道理。我目前无法做到这一点(需要一些思考和重构),但我相信我可以使用您的建议完成这项工作。在 Eclipse/RCP 环境中支持遗留代码的痛苦:)
    【解决方案2】:

    好吧,我不能 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.packageA.IWantToLoadThisClass 将从 com.tool.packageB 中可见,并且您可以在 jenv->FindClass("com/tool/packageA/IWantToLoadThisClass"); 时找到它。

    我希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2012-07-08
      • 2011-12-05
      • 2014-11-17
      • 2012-07-27
      • 2018-06-13
      • 1970-01-01
      • 2023-03-07
      • 2015-06-24
      • 1970-01-01
      相关资源
      最近更新 更多