Java 无法从OSGI捆绑包中获取类的类型化实例

Java 无法从OSGI捆绑包中获取类的类型化实例,java,osgi,Java,Osgi,我的应用程序中需要一个类A的实例,这个类A来自Bundle B osgi,位于该Bundle的包X中。 到目前为止我所做的: 我已将bundle B添加到本地maven存储库中,并将其作为具有“提供”范围的依赖项添加到pom中。 我还使用pom.xml中的动态导入将包X从类A所在的Bundle B添加到我的pom中。 这里需要注意的一点是,包X不是从包B导出的,但我知道它仍然可以工作,我见过同事们这样做,但我还不是很好 无论如何,我是如何尝试获取以下类的实例的: Bundle bundle; C

我的应用程序中需要一个类A的实例,这个类A来自Bundle B osgi,位于该Bundle的包X中。 到目前为止我所做的: 我已将bundle B添加到本地maven存储库中,并将其作为具有“提供”范围的依赖项添加到pom中。 我还使用pom.xml中的动态导入将包X从类A所在的Bundle B添加到我的pom中。 这里需要注意的一点是,包X不是从包B导出的,但我知道它仍然可以工作,我见过同事们这样做,但我还不是很好

无论如何,我是如何尝试获取以下类的实例的:

Bundle bundle;
Class<?> checkClass=bundle.loadClass("full path to class A");

TypeOfClassA newClass=checkClass.newInstance();
org.apache.felix.framework.BundleWiringImpl.findClassOrResourceByDelegationBundleWiringImpl.java:1532 在

org.apache.felix.framework.BundleWiringImpl.access$400BundleWiringImpl.java:75


但是为什么呢?我已经加载了jar,我正在使用bundle类加载器,而且如果我将checkClass转换为Object,我可以看到类A的方法和字段,所以看起来不错,我如何才能获得类A的实例?

在OSGi中,编译时和运行时之间存在差异。在编译时,您可以看到自己jar的类和maven的所有依赖项

在运行时,默认情况下,bundle只能看到它自己的类。任何其他包都需要清单中的Import-Package语句。通常,当您使用类时,bnd会自动创建该类。只要有可能,你就应该依靠这种自动性

您的案例当然不同,因为您想要访问的包不是由bundle B导出的。在这种情况下,无法通过您自己的bundle包的bundle classloader到达类A

相反,您需要使用bundle B的bundle类加载器。例如,您可以从BundleContext获取bundle B。然后你可以加载这个类

另一个选项是使用从Bundle B导出的类C,并使用类C的类加载器加载类A


无论如何,这是一次黑客攻击。您应该避免使用另一个bundle的私有类。

在OSGi中,编译时和运行时是有区别的。在编译时,您可以看到自己jar的类和maven的所有依赖项

在运行时,默认情况下,bundle只能看到它自己的类。任何其他包都需要清单中的Import-Package语句。通常,当您使用类时,bnd会自动创建该类。只要有可能,你就应该依靠这种自动性

您的案例当然不同,因为您想要访问的包不是由bundle B导出的。在这种情况下,无法通过您自己的bundle包的bundle classloader到达类A

相反,您需要使用bundle B的bundle类加载器。例如,您可以从BundleContext获取bundle B。然后你可以加载这个类

另一个选项是使用从Bundle B导出的类C,并使用类C的类加载器加载类A


无论如何,这是一次黑客攻击。您应该避免使用另一个bundle的私有类 PluginA test=PluginA classloader.loadclassPluginA.newInstance 然后您需要实际导入PluginA类,正如Christian所提到的,只有从其所在的包中导出PluginA类,才能导入PluginA类。以下方面应起作用:

Object test= classloader.loadclass("PluginA").newInstance()

然后,您需要使用反射来访问类的方法,等等 PluginA test=PluginA classloader.loadclassPluginA.newInstance 然后您需要实际导入PluginA类,正如Christian所提到的,只有从其所在的包中导出PluginA类,才能导入PluginA类。以下方面应起作用:

Object test= classloader.loadclass("PluginA").newInstance()

然后,您需要使用反射来访问类的方法,等等。

Christian,谢谢您的回答。我尝试使用Bundle类装入器,并且我能够获得类。问题是,我无法再次转换到类A,让我们称之为PluginA类。如果我使用PluginA test=PluginAglassloader.loadclassPluginA.newInstance,它再次抛出ClassNotFound,所以您使用了类A所在的捆绑包来加载类?嗨,Christian,是的,非常感谢大家的帮助,这并不像我想的那么简单,但人们总能学到新东西。Shi Christian,谢谢你的回答。我试着使用捆绑包类加载程序,我能够得到类。问题是我不能再次转换到类A,让我们称之为PluginA类。如果我去PluginA test=PluginAglassloader.loadclassPluginA.newInstance,它再次抛出ClassNotFound所以你使用类A所在的包来加载类?嗨,Christian,是的,非常感谢大家的帮助,这并不像我想象的那么简单,但人们总是可以学到新的东西。这是对的,事实证明,只有当我将反射与InvokationHandler和Proxy一起使用时,它才会起作用。newProxyInstance,谢谢,这是对的,事实证明,只有当我将反射与InvokationHa一起使用时,它才会起作用 ndler和Proxy.newProxyInstance,谢谢