一、osgi框架class加载机制
当一个模块(bundle)的类加载器遇到需要加载某个类或查找某个资源的请求时,
规则步骤如下:
1)如果在以java.*开头的package中,那么这个请求需要委派给父类加载器
2)如果在父类委派清单所列明的package中,还是委派给父类加载器 使用org.osgi.framework.bootdelegation属性
3)如果在import-package标记描述的package中,委派给导出这个包的bundle的类加载器
4)如果在require-bundle导入的一个或多个bundle的包中,就好安装require-bundle指定的bundle清单顺序逐一委派给对应bundle的类加载器
5 )搜索bundle内部的classpath
6)搜索每个附加的fragment bundle的classpath
7)如果在某个bundle已经声明导出的package中,或者包含在已经声明导入(import-package或require-bundle)的package中,搜索终止
8)如果在某个使用dynamicimport-package声明导入的package中,尝试在运行时动态导入这个package
9)如果可以确定找到一个合适的完成动态导入的bundle,委派给该bundle的类加载器
二、引入javax等jdk自带的包
日常开发中我们可能会用到需要引用java.* 的类,但是按照osgi class加载机制,javax下的包默认是不会用父类加载器,osgi提供了以下两种方式的相关配置可以解决。
- 使用org.osgi.framework.bootdelegation属性提示osgi使用父类加载器加载相应package
- 使用org.osgi.framework.system.packages.extra属性,确定那些包通过系统bundle来加载并export出来,使用对应的package时再在本bundle的MF 文件中去import可以。
三、引入第三方包
详细可如果bundle用到了第三方没有被bundle化的jar包,那么只有三种方式可以加载
- 通过父加载器加载(即用 第“引入javax等jdk自带的包”中的配置告知,不推荐,原则上只加载一些核心包,而且还需要将jar包传到服务器WEB-INF/framework 下)
- 将jar转换成bundle,并且export需要的package (推荐,此方式贴合OSGI规范,可复用性高,但是稍复杂可能调试过程中会遇到package 引入冲突问题) 将普通jar包转为符合OSGI规范的bundle形式,当作osgi底包,也需要上传到服务器。 操作方式利用eclipse官方推荐的方式:
- 新建eclipse工程,工程选择为Plug-in Development—>Plug-in from Existing JAR Archives;
- 点击Add External...按钮,添加已经下载好的jar包;
- 注意两点,一是最好在"This plug-in is targeted to run with:"中选择an OSGI framework:Standard,二是一般要把最下面的"Unzip the JAR archives into the project"选项清除,否则eclipse会把jar文件全部展开为.class文件树,最后点击Finish按钮就可以了。
- 将jar打包进引用方bundle (推荐 , 如果复用性不高此方式较为简单) 将第三方jar包加到bundle classpath 。
其他参考资料:
2、【OSGI加载第三方非bundle化jar包的几种方式】
3、【OSGI官网】