2

I am calling some C++ code that tries to load a Java class, e.g.

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

Now, the problem is that this class resides in an OSGi bundle, and the code above cannot find my class.

This problem only arise when running unit tests (Tycho-surefire headless tests). Is there a simple way to force the OSGi framework to find my class from JNI? On the Java side, I suspect something like Dynamic-ImportPackage could have fixed my problem. I am unwilling to change the third party C++ library just to get it working with the test framework, so I prefer a solution on the Java test setup / configuration side, if possible.

4

2 回答 2

5

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

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

于 2013-06-07T09:10:16.427 回答
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: registeredcom.tool.packageB MANIFEST.MF
  2. 添加Eclipse-RegisterBuddy: com.tool.packageBcom.tool.packageA MANIFEST.MF
  3. 添加Require-Bundle: com.tool.packageBcom.tool.packageA MANIFEST.MF

现在com.tool.packageA.IWantToLoadThisClass将从com.tool.packageB中可见,您将能够在jenv->FindClass("com/tool/packageA/IWantToLoadThisClass");.

我希望这有帮助。

于 2019-02-26T11:55:38.023 回答