osgi - 系统捆绑包如何访问系统包?
问题描述
在过去的几周里,我正在探索 OSGI 是如何实现的。我知道每个包都使用自己的类加载器来加载它的类。作为我调查的一部分,我了解到每个包的类加载器的父级都是空的,即引导类加载器。
System.out.println("ClassInBundle class is loaded by "+ClassInBundle.class.getClassLoader());
System.out.println("ClassInBundle parent class is "+ClassInBundle.class.getClassLoader().getParent());
捆绑样本包中的上述代码的输出是
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并且包 samplebundle 连接到com.test.packag的系统包 [0]。
因此,我想了解 system bundle[0] 如何访问由不同类加载器(App 类加载器)加载的系统包。不仅如此 OSGI 的所有核心类如 Bundle、BundleActivator、Felix 也由 App 类加载器加载。因此,我尝试调试 Felix 代码以了解系统捆绑包是否将 loadClass() 请求委托给 App 类加载器。不幸的是,在调试时我观察到 BundleWiringImpl 类的 m_wiring 变量,我注意到系统包的类加载器为空(这是不可能的,因为引导类加载器只加载 java.* 包)。
如果我错了,请纠正我的理解。
我的问题是
system_bundle[0] 的类加载器是什么,它的父类加载器是什么?
如果 system_bundle 类加载器的父类不是 App 类加载器,系统捆绑包是否还维护 package=>classloader 的映射以加载由应用类加载器加载的类?
类加载器(捆绑类加载器、系统类加载器、引导类加载器和应用程序类加载器)的层次结构到底是什么?
谢谢你。
解决方案
通常,OSGi 框架(又名 System Bundle)由应用程序加载程序加载,因此可以看到应用程序加载程序及其父项(即扩展加载程序和引导加载程序)上的所有其他内容。
这实际上取决于您如何编写启动器。您可以将 OSGi 嵌入到任何标准 Java 应用程序中,只需实例化 aFrameworkFactory
并使用它来启动Framework
. 当您这样做时,OSGi 框架只是类路径上的另一个库,并且它具有与您自己的代码相同的类集的可见性。
您可以根据自己的喜好使事情变得简单或花哨。例如,您可以将 OSGi 框架嵌入到部署在 J2EE 应用程序服务器中的 Servlet 中……在这种情况下,系统包将对 Web 应用程序中可用的所有类型具有可见性,由 WEB-INF 的内容控制。您甚至可以将 OSGi 框架嵌入到部署到另一个 OSGi 框架的包中…… OSGi 开始!
在所有这些情况下,框架可以选择要导出的包集。这些包可以通过该框架内的包导入。默认情况下,导出的包是相关 JavaSE 版本的标准 JavaSE 包集,但您可以添加其他应用程序级包。
推荐阅读
- c++ - Windows 多线程强制线程优先级
- javascript - 悬停在图像上时,仅显示光标所在的部分
- spring-boot - 有没有办法在春季启动测试中从 src/test/resources/application.properties 加载属性?
- python - 我在python的链表中遇到问题
- java - 在 Firebase 中搜索时如何执行 OR 查询?
- javascript - Javascript/html 文件无法在浏览器中正确打开???浏览器只是无限加载(在 safari 和 chrome 上尝试过)
- python - 在将数据添加到包含列表作为其值的字典中时,我以前的所有键都会更新为列表的最新值
- javascript - 从 firebase 读取如何工作?
- python - Pandas:ValueError:数组的长度必须相同 - 当 orient=index 不起作用时
- java - PKIX 路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:代理后面