OSGi教程 – 00 – OSGi是什么

OSGi是什么

OSGi(Open Service Gateway Initiative, “开放服务网关”)由OSGi联盟(OSGi Alliance)发起,其目的在于提供基于Java语言的动态模块化规范,而其内涵也已经远远超过了服务和网关的范畴,OSGi联盟给出的最新OSGi定义是The Dynamic Module System for Java,即面向Java的动态模块化系统。OSGi已经兼容了多种设备,并提供了对应用和服务进行远程管理和互操作的能力,它已经被众多世界知名公司所使用,遍布企业级软件、移动终端、智能家居、电信、消费电子等各类产品之中。

尽管Sun和Oracle一再宣称要提供内置于Java语言本身的模块化机制,但由于种种原因一直跳票,Oracle最近宣布将会在JDK9中解决JDK本身的模块化问题,并且会定义一个模块化的通用规范。而OSGi是到目前为止在Java语言范畴内解决应用程序模块化问题的最佳通用解决方案,也是唯一已经被证明并已经成熟的开放解决方案,并且已经成为事实上的Java模块化标准。

OSGi联盟官方宣称可以根据OSGi服务规范来创建可重用的组件,构建和管理高度复杂的系统,并且认为使用OSGi来编写Java程序是最酷的选择,使用它至少有如下优点:

● 使得代码变得更容易编写、测试和重用

● 能够管理动态部署

● 能够进行远程部署

● 更方面进行问题检测

● 更容易地进行问题调试

不过笔者希望大家不要忘记这一切的前提是:你需要面对的是一个“高度复杂”的系统。所谓杀鸡焉用牛刀,如果你只是要编写一个小规模、无需考虑太多扩展和模块化的应用程序,是否使用OSGi就仁者见仁智者见智了。

OSGi联盟

OSGi联盟成立于1999年3月,它是一个非盈利组织,负责提供OSGi相关的规范、参考实现、测试包和专业化认证。OSGi联盟的目的在于培养一个高价值的跨行业生态环境,为标准的制定者、技术的开发者和采用者发展OSGi技术提供便利,创造基于开放标准的解决方案。

OSGi联盟的成员包括各种服务和内容提供商、基础设施/网络运营商、公共事业单位、企业软件供应商、软件开发者、网关供应商、消费电子设备供应商、研究机构等,如华为、IBM、Adobe、Oracle、Eclipse、Red Hat、Hitachi、D-Link、TCL、TATA、东方通等。相信大家可能更专注其中的华为和东方通这两家中国公司,据侧面了解,华为的家庭网关、东方通的应用服务器都采用了OSGi技术。

OSGi联盟成员有4类:战略合作成员(Strategic Members)、主要成员(Principal Members)、贡献合伙人(Contributing Associates)、支持者(Supporters)。特别值得注意的是,华为是十个战略合作成员之一,这意味着OSGi技术在华为得到了较为深入的使用,另外国内的中间件厂商东方通也在支持者之列。

为了应对来自垂直领域和跨行业的需求,OSGi联盟以专家组的形式来提供对OSGi服务平台的裁剪和适配方面的服务,目前包括三个专家组:企业专家组(Enterprise Expert Group)、住宅专家组(Residential Expert Group)、核心平台专家组(Core Platform Expert Group)。也许身为读者的你也会成为其中某个专家组的一员呢!

OSGi联盟的官网网址为https://www.osgi.org/,读者可以自行浏览该网站了解更多信息。

OSGi架构

根据OSGi联盟的官方解释,OSGi体系架构如下图所示:

2016070301

开发者们所开发的OSGi组件都称为Bundle,Bundle是一组Java包、类、描述文件等资源的集合。OSGi体系架构分为5层:

● 服务(Services)层:服务通常使用Java接口来定义,由一个或多个Java对象实现,Bundle可以将服务注册并发布到OSGi运行环境中的服务注册表中。服务层以动态的方式连接各个Bundle,提供POJO的发布、查找、绑定机制。

● 生命周期(Life Cycle)层:提供安装、启动停止、更新、卸载Bundle的API。生命周期层规范定义了Bundle生命周期过程之中的6种状态:

○ UNINSTALLED(未安装):状态值为整型数1。此时Bundle中的资源是不可用的。

○ INSTALLED(已安装):状态值为整型数2。此时Bundle已经通过了OSGi框架的有效性校验并分配了Bundle ID,本地资源已加载,但尚未对其依赖关系进行解析处理。

○ RESOLVED(已解析):状态值为整数4。此时Bundle已经完成了依赖关系解析并已经找到所有依赖包,而且自身导出的Package已可以被其它Bundle导入使用。在此种状态的Bundle要么是已经准备好运行,要么就是被停止了。

○ STARTING(启动中):状态值为整型数8。此时Bundle的BundleActivator的start()方法已经被调用但是尚未返回。如果start()方法正常执行结束,Bundle将自动转换到ACTIVE状态; 否则如果start()方法抛出了异常,Bundle将退回到RESOLVED状态。

○ STOPPING(停止中):状态值为整型数16。此时Bundle的BundleActivator的stop()方法已经被调用但是尚未返回。无论stop()是正常结束还是抛出了异常,在这个方法退出之后,Bundle的状态都将转为RESOLVED。

○ ACTIVE(已激活):状态值为整型数32。Bundle处于激活状态,说明BundleActivator的start()方法已经执行完毕,如果没有其他动作,Bundle将继续维持ACTIVE状态。

如果要获取Bundle的状态,可以使用org.osgi.framework.Bundle接口定义的getState()方法。Bundle的状态图如下:

20160925_01

● 模块(Modules )层: 定义了Bundle的加载策略,如何导入和导出代码。OSGi对于每个实现了 BundleActivator 接口的 Bundle会生成一个单独的 ClassLoader。

● 安全(Security)层:处理安全相关的事务。

● 执行环境(Execution Environment)层:定义在指定的平台上哪些方法和类是可用的

特别要注意的一点是,OSGi运行在Java虚拟机之上,也就意味着它并不是Java语言本身的内置模块化机制,这对理解OSGi的历史和未来发展特别重要,我会在下一章节中进行更为详细的讲解。

规范历史

OSGi规范从2000年正式发布第1版到2014年发布第6版前后跨越了十五年,这十五年中OSGi从嵌入式设备起步,然后另辟蹊径独立发展,逐步在Java领域具备了重大的影响力(Eclipse IDE本身算是最成功、普及最广的产品之一),后来回归语言规范受阻,最终经各方博弈后在Java9中达成一致和妥协,其间的故事很多。网上有很多关于OSGi规范本身的资料就不再赘述,请大家自行查阅,下面我从JSR(Java Specification Requests,Java规范提案)的角度来对这段发展进行解读。

JSR8:开放服务网关规范(Open Services Gateway Specification)

规范内容位于:https://jcp.org/en/jsr/detail?id=8

JSR8由Sun于1999年发起,它定义了开放服务网关规范,当初定义其主要目标平台是用于智能家居、家庭或远程办公环境的嵌入式网关,即嵌入式的Java平台。该协议很快被撤回,原因是OSGi联盟也于1999年成立,相关的规范将放到OSGi联盟继续进行完善,独立发展,不再在JCP的控制之下前进。

其实我们回过头来看,目前在嵌入式设备、智能网关领域的应用仍是OSGi的重要战场,可以说OSGi是做到了不忘初心。

JSR 232: 移动运营管理(Mobile Operational Management)

规范内容位于:https://jcp.org/en/jsr/detail?id=232

JSR232的主要活时期是2003年至2008年,其中定义了OSGi作为J2ME手机应用领域的底层架构,标志着OSGi在嵌入式领域的成熟。

值得玩味的是该规范由摩托罗拉和诺基亚这两大当时的手机霸主主导,如果……可惜历史没有如果。

JSR 277: Java模块系统(Java Module System)

规范内容位于:https://jcp.org/en/jsr/detail?id=277

JSR277在2005年发起,在2016年才被撤回,理由是被JSR376替代了。JSR277主要将模块化的目标针对Java自身,它提出要解决JAR文件本身的一些缺陷,由于JAR格式产生于上个世纪90年代,其部署、版本管理、依赖引用机制都已经跟不上时代的发展,因此希望提出一个模块化系统来解决这些问题。

这个规范的发起者包括Oracle、Google、IBM、SAP、Red Hat等行业巨头,但是他们却一起上演了一场跨越十五年的肥皂剧,Java语言本身的发展在这十五年可以说是辉煌的十五年,也是堕落的十五年。

JSR 291: Java SE的动态组件支持(Dynamic Component Support for Java SE)

规范内容位于:https://jcp.org/en/jsr/detail?id=291

JSR291在2006年面世,明确指出它是基于JSR232的,它正式提出将OSGi从J2ME环境延伸到J2SE环境,在JavaSE平台上提供动态组件及生命周期管理解决方案。

JSR291的目标可谓野心勃勃,OSGi从JCP发起,出走独立发展获得了业界认可和标准制定影响力后,希望重新杀回Java语言规范,而且提出要在Java7中实现,一时间万众瞩目。我认为JSR291是OSGi联盟与JCP之间十五年肥皂剧的正式起点——诸位看官请注意,它的领导者是IBM而不是Oracle,Oracle大概在想:你TMD想走就走,想来就来,你以为你是谁?

JSR 294: Java编程语言中的模块化支持改进(Improved Modularity Support in the Java Programming Language)

规范内容位于:https://jcp.org/en/jsr/detail?id=294

JSR294也是2006年生的,也是在2016年才被撤回,理由是也被JSR376替代了。2006年JSR294先提出了一个叫超级包(superpackage)的概念,到2008年Oracle终于自己也被恶心坏了,改名叫模块(module)。不过它也没说自己错了,官方描述说叫模块是因为我们把超级包的概念简化了,现在更轻量,所以叫模块……呵呵。

这一次规范的领导者又变成Oracle了,他也说会在Java7中实现,不过最终也是没实现。这个潜台词是这样的:2006年,IBM说:OSGi的bundle在Java7中引进!然后Oracle就说:LZ搞个superpackage,也在Java7中引进,你想咋的……然后就没然后了。到了2008年,大家都恶心得差不多了,准备妥协:好吧,都退一下,我们一起重新来搞个module吧……不过刚刚互相扯过皮,抬头不见低头见挺不好意思的,还是等过几年再搞吧!

JSR 376:Java平台模块系统(Java Platform Module System)

规范内容位于:https://jcp.org/en/jsr/detail?id=376

JSR376是2014年生的,它的介绍中也明确提到了JSR291想把OSGi纳入Java语言机制这件事情,而且也非常一针见血地指出:OSGi是运行在Java之上,而不是在Java语言原生的。但是也给予了OSGi极大的尊重,基本上表示你的意见我都认可,除了你不是在语言之中——所以我们必须提出伟大的Module概念,并且将范畴从J2ME拓展到J2SE、J2EE。

这一次的领导者还是Oracle,不过除了IBM、Red Hat这些常客之外,加入了一个非常重要的角色:Eclipse——我猜他可能是IBM的重要掮客,毕竟Eclipse IDE大家都混了个眼熟,红道白道都认识,这样终于把大家勾兑好了。这次基本上就是接上JSR294的话了:十五年过去了,Java9咱们继续搞起,语言上大家一起提出新的模块化概念(模块化一定要叫Module,嘿嘿),对OSGi也提供兼容的机制,从而使过去的投资得以保护,并且哥让你们用钛合金眼看看什么叫实力:我还把JavaSE、JavaEE都搞定!

OSGi的未来

我听到过很多关于采用OSGi的讨论、分析、赞誉和埋怨,现在基本可以给出结论性的说明了:OSGi的本质是模块化,不管你学与不学OSGi,模块化都会回到Java语言之中(所以我前文说是失落的十五年),或许OSGi会换一个马甲,但基本可以肯定会有一个兼容机制——Java程序员们,期待合体吧!

笔者注:个人觉得OSGi与JSR规范变迁这段历史颇有意思,如果能配几幅漫画可能更为生动,无奈我画工不行,如果有读者能补上这个小遗憾就好了。

打赏一下
支付宝
微信
除非注明,博客文章均为原创,转载请标明文章地址
本文地址: http://www.javafxchina.net/blog/2016/07/osgi-00-what/
百度已收录