我遇到以下情况:我的应用程序中需要一个类A的实例,该类A来自Bundle B(osgi),位于该Bundle中的包X中。 到目前为止,我所做的是: 我已经将包B添加到本地Maven存储库,并将其作为具有“提供”范围的依赖项添加到我的pom中。 我还从Bundle B中添加了软件包X,其中,类A通过我的pom.xml中的Dynamic-import驻留在我的pom中。 这里要注意的一件事-包X并不是从捆绑软件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,我正在使用捆绑类加载器,如果我将checkClass转换为Object,我也可以看到Class A的方法和字段,因此看起来不错,如何获得Class A的实例?
答案 0 :(得分:2)
在OSGi中,编译时间和运行时之间有所不同。在编译时,您会看到自己的jar的类以及来自maven的所有依赖项。
在运行时,捆绑包默认情况下仅看到其自己的类。其他任何软件包都需要清单中的Import-Package语句。通常,当您使用类时,它会由bnd自动创建。只要有可能,您都应该依靠这种自动化。
您的情况当然有所不同,因为要访问的包不是由捆绑包B导出的。在这种情况下,无法通过自己捆绑包的捆绑包类加载器到达A类。
相反,您需要使用捆绑软件B的捆绑软件类加载器。例如,您可以从BundleContext获取捆绑软件B。然后您可以加载该类。
另一种选择是使用从捆绑软件B导出的类C,并使用类C的类加载器加载类A。
无论如何这都是黑客。您应该避免使用其他捆绑软件的私有类。
答案 1 :(得分:2)
当您写类似
PluginA test=(PluginA) classloader.loadclass("PluginA").newInstance()
那么您实际上需要导入PluginA类,正如Christian所提到的,只有从它所在的包中导出该类时才有可能。
Object test= classloader.loadclass("PluginA").newInstance()
然后,您将需要使用反射来访问类的方法,等等。