系统bundle如何访问系统包



在过去的几周里,我正在探索OSGI是如何实现的。我知道每个bundle都使用自己的类加载器来加载它的类。作为调查的一部分,我了解到每个捆绑包的类加载器的父级都是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.package被添加为FelixConstants.FRAMEWORK_SYSTEMPACKES,并且bundle samplebundle被连接到com.test.package.的系统bundle[0]

因此,我想了解系统捆绑包[0]如何访问由不同的类加载器(App类加载器)加载的系统包。不仅如此,OSGI的所有核心类,如Bundle、BundleActivator、Felix,也都由App类加载器加载。因此,我尝试调试Felix代码,以了解系统捆绑包是否将loadClass()请求委托给App类加载器。不幸的是,在调试时,我观察到BundleWiringImpl类的m_wiring变量,我注意到系统捆绑包的类加载器是null(这是不可能的,因为引导类加载器只加载java.*包)。

如果我错了,请纠正我的理解。

我在这里的问题是

systembundle[0]的类加载器是什么?它的父类加载器是多少?

如果system_bundle类加载器的父类不是应用程序类加载器,那么系统捆绑包是否也在维护package=>classloader的映射,以加载由应用程序类加载程序加载的类?

类加载器(bundle类加载器、系统类加载器、引导类加载器和应用程序类加载器)的层次结构究竟是什么?

谢谢。

通常情况下,OSGi框架(也称为系统捆绑包)由应用程序加载程序加载,因此可以查看应用程序加载器及其父级(即扩展加载程序和引导加载程序)上的所有其他内容。

这实际上取决于你如何编写你的启动器。只需实例化FrameworkFactory并使用它启动Framework,就可以将OSGi嵌入到任何标准Java应用程序中。当您这样做时,OSGi框架只是类路径上的另一个库,并且它具有与您自己的代码相同的类集的可见性。

你可以随心所欲地把事情做得简单或花哨。例如,可以将OSGi框架嵌入到部署在J2EE应用程序服务器中的Servlet中。。。在这种情况下,系统捆绑包将对Web应用程序中可用的所有类型具有可见性,由Web-INF的内容控制。您甚至可以将OSGi框架嵌入到部署到另一个OSGi框架的捆绑包中。。。OSGi启动!

在所有这些情况下,Framework都可以选择要导出的包集。这些包可以通过该框架内的捆绑包导入。默认情况下,导出的包是相关JavaSE版本的标准JavaSE包集,但您可以使用其他应用程序级包进行扩充。

相关内容

  • 没有找到相关文章

最新更新