我正在探索最近几周如何实施OSGI。我知道每个捆绑软件都使用自己的类加载器来加载其类。作为调查的一部分,我了解每个捆绑软件的类加载器的父级为null,即引导类加载器。
System.out.println("ClassInBundle class is loaded by "+ClassInBundle.class.getClassLoader());
System.out.println("ClassInBundle parent class is "+ClassInBundle.class.getClassLoader().getParent());
捆绑在 samplebundle 中的上述代码的输出为
ClassInBundle class is loaded by com.sample.bundle.samplebundle [34]
ClassInBundle parent class is null
对于捆绑包中的导入,它会维护packagename => classloader的映射,以便可以将请求委派给正确的类加载器
Bundle SB = felix.getBundleContext().getBundle(0);
List<BundleWire> sbwires=SB.adapt(BundleWiring.class).getRequiredWires(null);
List<BundleWire> li=bundle.adapt(BundleWiring.class).getRequiredWires(null);
for(BundleWire i : li){
System.out.println(i);
}
以上代码的输出为
[com.sample.bundle.samplebundle [34](R 34.0)] osgi.wiring.package; (osgi.wiring.package=com.test.packag) -> [org.apache.felix.framework [0](R 0)]
[com.sample.bundle.samplebundle [34](R 34.0)] osgi.wiring.package; (&(osgi.wiring.package=org.osgi.framework)(version>=1.8.0)(!(version>=2.0.0))) -> [org.apache.felix.framework [0](R 0)]
[com.sample.bundle.samplebundle [34](R 34.0)] osgi.wiring.package; (&(osgi.wiring.package=org.osgi.framework.wiring)(version>=1.2.0)(!(version>=2.0.0))) -> [org.apache.felix.framework [0](R 0)]
[com.sample.bundle.samplebundle [34](R 34.0)] osgi.ee; (&(osgi.ee=JavaSE)(version=1.6)) -> [org.apache.felix.framework [0](R 0)]
如您在上述输出的第一行中所见,软件包 com.test.packag 被添加为 FelixConstants.FRAMEWORK_SYSTEMPACKAGES ,并将bundle samplebundle连接到< com.test.packag 的strong>系统捆绑[0] 。
因此,我想了解系统bundle [0]如何访问由不同的类加载器(App类加载器)加载的系统软件包。 App类加载器不仅可以加载OSGI的所有核心类(例如Bundle,BundleActivator,Felix)。因此,我尝试调试Felix代码以了解系统捆绑包是否将loadClass()请求委托给App类加载器。不幸的是,在调试时,我观察到BundleWiringImpl类的m_wiring变量,但我发现系统捆绑包的类加载器为 null (这是不可能的,因为引导类加载器仅加载java。*包)。
如果我错了,请纠正我的理解。
我的问题是
system_bundle [0]的类加载器是什么,其父类加载器是什么?
如果system_bundle类加载器的父级不是App类加载器,系统捆绑包还会维护package => classloader的映射来加载由应用类加载器加载的类吗?
类加载器(捆绑类加载器,系统类加载器,引导类加载器和应用类加载器)的层次结构到底是什么?
谢谢。
答案 0 :(得分:4)
通常OSGi框架(也称为系统捆绑包)由应用程序加载器加载,因此可以查看应用程序加载器及其父级(即扩展加载器和引导加载器)上的所有其他内容。
这实际上取决于您如何编写启动器。您只需实例化FrameworkFactory
并使用它启动Framework
就可以将OSGi嵌入到任何标准Java应用程序中。当您执行此操作时,OSGi框架只是类路径上的另一个库,并且具有与您自己的代码相同的类集的可见性。
您可以根据自己的喜好使事情变得简单或幻想。例如,您可以将OSGi框架嵌入到J2EE应用程序服务器中部署的Servlet中……在这种情况下,系统捆绑包将具有对Web应用程序中所有可用类型的可见性, WEB-INF的内容。您甚至可以将OSGi框架嵌入到部署到另一个OSGi框架的捆绑软件中……OSGi诞生!
在所有这些情况下,框架都可以选择要导出的软件包集。这些软件包可以通过该Framework内的捆绑软件导入。默认情况下,导出的软件包是相关JavaSE版本的标准JavaSE软件包集,但是您可以使用其他应用程序级软件包进行扩充。