OSGi Bundle
OSGi Framework looks like OS,
Bundle looks like program,
OS can create a process to run program with its main function,
OSGi can start a Bundle with its Activator,
A process of OS has its features,
A bundle of OSGi has its state and features.
A process of OS can service for or communicate with other program,
A bundle of OSGi too
Reference:http://www.ibm.com/developerworks/cn/education/opensource/os-eclipse-osgi/section4.html
重要的理论知识
好的,刚才我们已经从头到尾开发了一个基于 Equinox 框架的 Hello world 应用程序。我们发现似乎并不是很困难,很多工作 Eclipse 已经帮我们做好了,例如 Activator 代码框架和 MANIFEST.MF 文件,我们也学会了如何控制 OSGi 的控制台和编写 MANIFEST.MF 文件,但是,您真的明白它们是如何运行的么?下面我们将重点介绍一些 OSGi 运行必备的基础知识。
什么是 bundle?
我们已经看到,编写一个很普通的 Hello world 应用,必须首先创建一个 plug-in 工程,然后编辑其 Activator 类的 start 方法,实际我们这样做的本质是为 OSGi 运行环境添加了一个 bundle,那么一个 bundle 必须的构成元素是哪些呢?
- MANIFEST.MF:描述了 bundle 的所有特征,包括名字、输出的类或者包,导入的类或者包,版本号等等,具体可以参考 表 2. MANIFEST.MF 文件属性。
- 代码:包括 Activator 类和其它一些接口以及实现,这个和普通的 Java 应用程序没有什么特殊的区别。
- 资源:当然,一个应用程序不可能没有资源文件,比如图片、properties 文件、XML 文件等等,这些资源可以随 bundle 一起存在,也可以以 fragment bundle 的方式加入。
- 启动级别的定义:可以在启动前使用命令行参数指定,也可以在运行中指定,具体的 start level 的解释,请参考 后面的说明。
框架做了些什么?
好了,我们已经明白 bundle 是什么了,也知道如何开发一个基本的 bundle 了,那么我们还必须要明白,我的 bundle 放在 Equinox 框架中,它对我们的 bundle 做了些什么?
图 11. Equinox 框架架构

实际上,目标平台已经为我们准备了 N 个 bundle,它们提供各种各样的服务,OSGi 中,这些 bundle 的名字叫 system bundle,就好比精装修的房子,您只需要拎包入住,不再需要自己铺地板,装吊顶了。
我们的 bundle 进入 Equinox 环境后,OSGi 框架对其做的事情如下:
- 读入 bundle 的 headers 信息,即 MANIFEST.MF 文件;
- 装载相关的类和资源;
- 解析依赖的包;
- 调用其 Activator 的
start方法,启动它; - 为其提供框架事件、服务事件等服务;
- 调用其 Activator 的
stop方法,停止它;
Bundle 的状态变更
OK, 现在我们大概明白了一个 bundle 的定义和其在 OSGi 框架中的生命周期,前面我们看到控制台可以通过 ss 命令查看所有装载的 bundle 的状态,那么 bundle 到底具有哪些状态,这些状态之间是如何变换呢?我们知道了这些状态信息,对我们有何益处?
首先,了解一下一个 bundle 到底有哪些状态:
表 3. Bundle 状态表
| 状态名字 | 含义 |
INSTALLED
|
就是字面意思,表示这个 bundle 已经被成功的安装了 |
RESOLVED
|
很常见的一个状态,表示这个 bundle 已经成功的被解析(即所有依赖的类、资源都找到了),通常出现在启动前或者停止后 |
STARTING
|
字面意思,正在启动,但是还没有返回,所以您的 Activator 不要搞的太复杂 |
ACTIVE
|
活动的,这是我们最希望看到的状态,通常表示这个 bundle 已经启动成功,但是不意味着您的 bundle 提供的服务也是 OK 的 |
STOPPING
|
字面意思,正在停止,还没有返回 |
UNINSTALLED
|
卸载了,状态不能再发生变更了 |
下面请看一张经典的 OSGi bundle 变更状态的图:
图 12. OSGi bundle 变更状态图

Bundle 导入导出 package
OK,到现在为止,似乎一切都是新鲜的,但是您似乎在考虑,OSGi 到底有什么优势,下面介绍一下其中的一个特点,几乎所有的面向组件的框架都需要这一点来实现其目的:
面向服务、封装实现
。这一点在普通的 Java 应用是很难做到的,所有的类都暴露在 classpath 中,人们可以随意的查看您的实现,甚至变更您的实现。这一点,对于希望发布组件的公司来说是致命的。
图 13. OSGi bundle 原理

OSGi 很好的解决了这个问题,就像上面的图显示的,每个 bundle 都可以有自己公共的部分和隐藏的部分,每个 bundle 也只能看见自己的公共部分、隐藏部分和其它 bundle 的公共部分。
bundle 的 MANIFEST.MF 文件提供了 EXPORT/IMPORT package 的关键字,这样您可以仅仅 export 出您希望别人看到的包,而隐藏实现的包。并且您可以为它们编上版本号,这样可以同时发布不同版本的包。
Bundle class path
这一点比较难理解,一般情况下您不需要关心这个事情,除非事情出现了问题,您发现明明这个类就在这里,怎么就是报告
ClassNotFoundException/NoClassDefExcpetion 呢?在您垂头丧气、准备砸掉电脑显示器之前,请看一下
bundle 中的类是如何查找的:
- 首先,它会找 JRE,这个很明显,这个实际是通过系统环境的
JAVA_HOME中找到的,路径一般是 JAVA_HOME/lib/rt.jar、tools.jar 和 ext 目录,endorsed 目录。 - 其次,它会找 system bundle 导出的包。
- 然后,它会找您的 import 的包,这个实际包含两种:一种是直接通过 require-bundle 的方式全部导入的,还有一种就是前面讲的通过 import package 方式导入的包。
- 查找它的 fragment bundle,如果有的话。
- 如果还没有找到,则会找自己的 classpath 路径(每个 bundle 都有自己的类路径)。
- 最后它会尝试根据 DynamicImport-Package 属性查找的引用。
启动级别 Start level
在 Equinox 环境中,我们在配置 hello world 应用的时候,看到我们将 framework start
level 保持为 4,将 Hello world bundle 的 start level 设置为 5 。 start level
越大,表示启动的顺序越靠后。在实际的应用环境中,我们的 bundle
互相有一定的依赖关系,所以在启动的顺序上要有所区别,好比盖楼,要从打地基开始。
实际上,OSGi 框架最初的 start level 是 0,启动顺序如下:
- 将启动级别加一,如果发现有匹配的 bundle(即 bundle 的启动级别和目前的启动级别相等),则启动这个 bundle;
- 继续第一步,直到发现已经启动了所有的 bundle,且活动启动级别和最后的启动的 bundle 启动级别相同。
停止顺序,也是首先将系统的 start level 设置为 0:
- 由于系统当前活动启动级别大于请求的 start level,所以系统首先停止等于当前活动启动级别的 bundle;
- 将活动启动级别减一,继续第一步,直到发现活动启动级别和请求级别相等,都是 0。
OSGi Bundle的更多相关文章
- OSGi Bundle之Hello World
开发一个简单的Hello World的OSGi Bundle(OSGi绑定包) 在OSGi中,软件是以Bundle的形式发布的.一个Bundle由Java类和其它资源构成,它可为其它的Bundle提供 ...
- [转]Eclipse插件开发之基础篇(5) 制作OSGi Bundle
原文地址:http://www.cnblogs.com/liuzhuo/archive/2010/08/18/eclipse_plugin_1_2_2.html 1. 生成OSGi工程 首先打开新工程 ...
- OSGi之Bundle
OSGi提出的根源是什么?在我看来就是对JVM的类加载机制进行了扩展,添加了一系列的规则,使得原有的类包(Class Package)扩展到类域(Class Domain).然后是建立在类域上的一系列 ...
- OSGI动态加载删除Service bundle
OSGi模块化框架是很早就出来的一个插件化框架,最早Eclipse用它而出名,但这些年也没有大热虽然OSGi已经发布了版本1到版本5.现在用的最多的,也是本文讲述基于的是Equinox的OSGi实现, ...
- Elipse plugin or Bundle & OSGI
Develop and register service, lookup and use service! Android Design on service's publish-find-bind ...
- OSGi系列 - 使用Eclipse查看Bundle源码
使用Eclipse开发OSGi Bundle时,会发现有很多现成的Bundle可以用.但如何使用这些Bundle呢?除了上网搜索查资料外,阅读这些Bundle的源码也是一个很好的方法. 本文以org. ...
- Liferay7 BPM门户开发之38: OSGi模块化Bndtools、Maven、Gradle开发构建入门
前言 OSGi是目前动态模块系统的事实上的工业标准,它适用于任何需要模块化.面向服务.面向组件的应用程序.Eclipse如此庞大和复杂的插件体系,就是基于OSGi.Liferay也是基于OSGi.OS ...
- 转:OSGi 入门篇:生命周期层
OSGi 入门篇:生命周期层 前言 生命周期层在OSGi框架中属于模块层上面的一层,它的运作是建立在模块层的功能之上的.生命周期层一个主要的功能就是让你能够从外部管理应用或者建立能够自我管理的应用(或 ...
- osgi dm
看了http://developer.51cto.com/art/200909/154863.htm 真心感到,最强大最有组织的技术网站还是 51cto,牛人应该也是最多的. 以前逛51cto的比较少 ...
随机推荐
- Windows Server 2008 R2中IIS7.5配置完网站权限不足问题的解决办法:
Windows Server 2008 R2中IIS7.5配置完网站权限不足问题的解决办法:常见问题:HTTP 错误 500.0 - Internal Server Error无法显示页面,因为发生内 ...
- flask之werkzeug
密码存储的主要形式: 明文存储:肉眼就可以识别,没有任何安全性. 加密存储:通过一定的变换形式,使得密码原文不易被识别. 密码加密的几类方式: 明文转码加密:BASE64, 7BIT等,这种方式只是个 ...
- C++_类继承3-动态联编和静态联编
程序调用函数时,将使用哪个可执行代码块呢?编译器负责回答这个问题. 将源代码中的函数调用解释为特定的函数代码块被称为函数名联编(binding). 在C语言中,这非常简单,因为每个函数名对应一个不同的 ...
- rest-framework框架之序列化
rest-framework框架之序列化 开发 API 接口最重要的工作就是将代码片段的输出序列化和反序列化为类似于 json 的表示形式. 在 rest-framework 中,通过声明与 Djan ...
- [BZOJ 4850][Jsoi2016]灯塔
传送门 #include <bits/stdc++.h> using namespace std; #define rep(i,a,b) for(int i=a;i<=b;++i) ...
- Mysql Update更新错误 Error Code:1175
Mysql 5.7,默认执行 update 语句时遇到错误提示: Error Code: 1175. You are using safe update mode and you tried to u ...
- 【算法笔记】B1037 在霍格沃茨找零钱
1037 在霍格沃茨找零钱 (20 分) 如果你是哈利·波特迷,你会知道魔法世界有它自己的货币系统 —— 就如海格告诉哈利的:“十七个银西可(Sickle)兑一个加隆(Galleon),二十九个纳特( ...
- npm install时 报错Maximum call stack size exceeded
给npm降级或者升级 降级 : npm install -g npm@5.4.0 升级 : npm install -g npm 升级到最新版
- 江西理工大学南昌校区排名赛 C: 单身狗的地图游戏
题目描述 萌樱花是一只单身狗. 萌樱花今天决定去喜欢的学妹家玩,但他不记得路,于是他拿出有n个点的完全图,选取了k条不同的路. 完全图:n 个点的图中任意两个点之间都有一条边相连,所以有 n*(n-1 ...
- 学习python-跨平台获取键盘事件
class _Getch: """Gets a single character from standard input. Does not echo to the sc ...