系统包如何访问系统包?

how does system bundle has access to system packages?

我在过去几周研究了 OSGI 是如何实现的。我知道每个包都使用自己的 class 加载程序来加载其 classes。作为我调查的一部分,我了解到每个包的 class 加载器的父级都是空的,即引导 class 加载器。

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 的映射,以便它可以将请求委托给正确的 class loader

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 并且包 samplebundle 连接到 system bundle[0] for com.test.packag.

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

如有错误请指正

我的问题是

system_bundle[0] 的 class 加载程序是什么,它的父 class 加载程序是什么?

如果 system_bundle class loader 的父类不是 App class loader,system bundle 是否也维护 package=>classloader 的映射来加载class由应用程序加载的 es class loader?

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

谢谢。

通常 OSGi 框架(又名系统包)由应用程序加载器加载,因此可以看到应用程序加载器及其父项(即扩展加载器和引导加载器)上的所有其他内容。

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

您可以根据自己的喜好使事情变得简单或花哨。例如,您 可以 将 OSGi 框架嵌入到部署在 J2EE 应用程序服务器中的 Servlet 中......在这种情况下,系统包将对 Web 应用程序中可用的所有类型具有可见性,因为由 WEB-INF 的内容控制。您甚至可以将 OSGi 框架嵌入到部署到另一个 OSGi 框架的包中...OSGi 启动!

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