我有以下情况。我的应用程序中需要一个类 A 的实例,而这个类 A 来自 Bundle B (osgi) 并且位于该 Bundle 的包 X 中。 到目前为止我做了什么: 我已将 bundle B 添加到本地 Maven 存储库,并将其作为具有“提供”范围的依赖项添加到我的 pom。 我还从 Bundle B 添加了包 X,其中 A 类驻留在我的 pom 中,并在我的 pom.xml 中使用动态导入。 这里要注意一件事——包 X 不是从 Bundle B 导出的,但我知道它仍然可以工作,我已经看到同事这样做了,但我还不是那么好。
无论如何,我是如何尝试获取下面类的实例的:
Bundle bundle;
Class<?> checkClass=bundle.loadClass("full path to class A");
TypeOfClassA newClass=checkClass.newInstance();
我得到了:
java.lang.ClassNotFoundException ClassA not found by myapplication
at
org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegation(BundleWiringImpl.java:1532) 在
org.apache.felix.framework.BundleWiringImpl.access$400(BundleWiringImpl.java:75)
但为什么呢?我已经加载了 jar,我正在使用 bundle 类加载器,如果我将 checkClass 转换为 Object,我可以看到 A 类的方法和字段,看起来不错,我如何获得 A 类的实例?
最佳答案
在 OSGi 中,编译时和运行时是有区别的。在编译时,您会看到自己的 jar 的类和来自 maven 的所有依赖项。
在运行时,默认情况下,一个包只能看到它自己的类。任何其他包都需要在 list 中包含 Import-Package 语句。通常这是在您使用类时由 bnd 自动创建的。只要有可能,您就应该依靠这种自动化。
你的情况当然是不同的,因为你想要访问的包不是由 bundle B 导出的。在这种情况下,无法通过你自己的 bundle 的 bundle 类加载器到达类 A。
相反,您需要使用 bundle B 的 bundle 类加载器。例如,您可以从 BundleContext 获取 bundle B。然后你可以加载类。
另一种选择是使用从 Bundle B 导出的类 C,并使用类 C 的类加载器加载类 A。
无论如何,这是一个 hack。您应该避免使用另一个包的私有(private)类。
关于java - 无法从 OSGI 包中获取类型化的类实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58310993/