系统包如何访问系统包?

问题描述 投票:5回答:1

我正在探索过去几周如何实施OSGI。我知道每个bundle都使用自己的类加载器来加载它的类。作为我调查的一部分,我理解每个bundle的类加载器的父级是null,即引导类加载器。

System.out.println("ClassInBundle class is loaded by "+ClassInBundle.class.getClassLoader());
System.out.println("ClassInBundle parent class is "+ClassInBundle.class.getClassLoader().getParent());

bundle samplebundle中上面代码的输出是

ClassInBundle class is loaded by com.sample.bundle.samplebundle [34]
ClassInBundle parent class is null

对于bundle中的导入,它维护一个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的系统包[0]。

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

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

我的问题是

system_bundle [0]的类加载器是什么,它的父类加载器是什么?

如果system_bundle类加载器的父级不是App类加载器,系统包是否还维护package => classloader的映射来加载由app类加载器加载的类?

类加载器的层次结构究竟是什么(bundle类加载器,系统类加载器,引导类加载器和app类加载器)?

谢谢。

osgi apache-felix equinox dynamic-class-loaders embedded-osgi
1个回答
4
投票

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

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

你可以根据自己的喜好制作简单或花哨的东西。例如,您可以将OSGi Framework嵌入到J2EE应用程序服务器中部署的Servlet中......在这种情况下,系统包将可以看到Web应用程序中可用的所有类型,这由WEB-INF的内容控制。您甚至可以将OSGi框架嵌入到部署到另一个OSGi框架的软件包中...... OSGi开始了!

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

© www.soinside.com 2019 - 2024. All rights reserved.