OSGi是怎么解决的?

我已经阅读了维基百科和其他关于OSGi的网站,但是我并没有真正看到大局。 它说这是一个基于组件的平台,您可以在运行时重新加载模块。 Eclipse插件框架也是“实例”。

我的问题是:

  1. OSGi的清晰和简单的定义是什么?

  2. 它解决了什么共同的问题?

“常见问题”指的是我们每天面对的问题,比如“OSGi为了使我们的工作更高效,更有趣,更简单而做些什么?

我从OSGi发现了以下好处:

  • 每个插件都是具有自己的类加载器的版本化工件。
  • 每个插件都依赖于它包含的特定jar以及其他特定的版本化插件。
  • 由于版本控制和独立的类加载器,同一个工件的不同版本可以同时加载。 如果应用程序的一个组件依赖于一个插件版本,另一个组件依赖于另一个版本,则它们都可以同时加载。

借此,您可以将应用程序构build为一组按需加载的版本化插件工件。 每个插件是一个独立的组件。 就像Maven帮助你构build你的构build一样,它是由它创build的一组特定版本的可重复和定义的,OSGi可以帮助你在运行时做到这一点。

OSGi的组件系统为您提供什么好处?
那么,这里有一个列表:

减less复杂性 –使用OSGi技术进行开发意味着开发bundle:OSGi组件。 包是模块。 他们把内部的东西隐藏起来,通过明确的服务进行交stream。 隐藏内部意味着更多的自由来改变。 这不仅减less了错误的数量,而且还使得bundle更容易开发,因为正确大小的bundle通过定义良好的接口来实现一个function块。 有一个有趣的博客描述了OSGi技术的发展过程。

重用 – OSGi组件模型使得在应用程序中使用许多第三方组件非常容易。 越来越多的开源项目提供了为OSGi准备的JAR。 然而,商业图书馆也正在成为现成的捆绑包。

真实世界 – OSGi框架是dynamic的。 它可以即时更新捆绑,服务可以来去。 习惯于更传统的Java的开发人员认为这是一个非常有问题的function,并没有看到优势。 然而,事实certificate,真实世界是高度dynamic的,并且具有dynamic服务可以来来去去,使服务与许多真实世界场景完美匹配。 例如,服务可以模拟networking中的设备。 如果检测到该设备,则该服务被注册。 如果设备消失,则该服务未注册。 与这种dynamic服务模型相匹配的真实世界场景数量惊人。 因此,应用程序可以在自己的域中重用服务registry的强大基元(注册,获取,具有expressionfilter语言的列表,并等待服务出现和消失)。 这不仅节省了编写代码,而且还提供了全球可见性,debugging工具以及比专门解决scheme更多的function。 在这样一个dynamic的环境中编写代码听起来像是一场噩梦,但幸运的是,有支持类和框架可以消除大部分(如果不是全部的话)的痛苦。

轻松部署 – OSGi技术不仅仅是组件的标准。 它还指定组件的安装和pipe理方式。 这个API已经被许多bundle用来提供pipe理代理。 此pipe理代理可以像命令shell,TR-69pipe理协议驱动程序,OMA DM协议驱动程序,Amazon EC2的云计算接口或IBM Tivolipipe理系统一样简单。 标准化的pipe理API使得将OSGi技术集成到现有和未来的系统变得非常容易。

dynamic更新 – OSGi组件模型是一个dynamic模型。 可以在不closures整个系统的情况下安装,启动,停止,更新和卸载软件包。 许多Java开发人员不相信这可以可靠地完成,因此最初不在生产中使用。 但是,在开发一段时间之后,大多数人开始意识到它的实际运行并大大减less了部署时间。

自适应 – OSGi组件模型是从零开始devise的,以允许组件的混合和匹配。 这就要求组件的依赖关系需要被指定,并且它需要组件存在于其可选依赖不总是可用的环境中。 OSGi服务registry是一个dynamicregistry,其中bundle可以注册,获取和监听服务。 这个dynamic的服务模型允许bundle找出系统上可用的function,并调整它们可以提供的function。 这使得代码更灵活,更具弹性。

透明度 –捆绑和服务是OSGi环境中的一等公民。 pipe理API提供对软件包内部状态的访问以及如何连接到其他软件包。 例如,大多数框架提供了一个显示这个内部状态的命令shell。 部分应用程序可以停止debugging某个问题,或者可以引入诊断包。不要盯着数百万行日志输出和很长的重启时间,OSGi应用程序通常可以使用活动命令shell进行debugging。

版本控制 – OSGi技术解决JAR地狱。 JAR地狱是库A与库B工作的问题;版本= 2,但库C只能与B工作;版本= 3。 在标准的Java中,你运气不好。 在OSGi环境中,所有捆绑包都经过仔细的版本控制,只有可以协作的捆绑包才能在同一个类空间中连接在一起。 这允许包A和C与它们自己的库一起运行。 虽然不build议devise具有这个版本问题的系统,但在某些情况下它可能是一个挽救生命的东西。

简单 – OSGi API非常简单。 核心API只有一个包,less于30个类/接口。 这个核心API足以编写包,安装它们,启动,停止,更新和卸载它们,并包含所有的侦听器和安全类。 很less有API为这么小的API提供如此多的function。

小 – OSGi第4版框架可以在大约300KB的JAR文件中实现。 这是通过包含OSGi添加到应用程序的function量的一个小开销。 因此,OSGi运行在大量的设备上:从非常小的到小的到大型机。 它只要求一个最小的Java虚拟机运行,并在其上添加很less。

快速 – OSGi框架的主要职责之一是从bundle中加载类。 在传统的Java中,JAR是完全可见的,并放置在一个线性列表中。 search一个类需要通过search(通常很长,150并不less见)列表。 相比之下,OSGi预先捆绑并知道每个捆绑包究竟是哪个捆绑包提供的类。 这种缺乏search是启动时显着的加速因素。

懒惰 –懒惰的软件是好的,OSGi技术有很多机制,只有在真正需要的时候才能做事。 例如,bundle可以被急切地启动,但是它们也可以被configuration为仅在其他bundle正在使用时才启动。 服务可以注册,但只有在使用时才能创build。 规格已经被优化了好几次,以允许这种懒惰的情况,可以节省巨大的运行时间成本。

安全 – Java在底层有一个非常强大的细粒度安全模型,但实际上很难configuration。 结果是大多数安全的Java应用程序都以二进制select运行:没有安全性或function非常有限。 OSGi安全模型利用细粒度的安全模型,但通过让开发人员以易于审核的forms指定请求的安全细节,同时环境的运营商仍然全面负责,提高了可用性(以及加固原始模型)。 总的来说,OSGi可能提供了最安全的应用程序环境之一,在硬件保护的计算平台上仍然可用。

非侵入性 – OSGi环境中的应用程序(捆绑)是自己的。 他们几乎可以使用虚拟机的任何设施,而不受OSGi的限制。 OSGi的最佳实践是编写简单的旧Java对象,因此OSGi服务不需要特殊的接口,甚至Java String对象也可以充当OSGi服务。 这个策略使应用程序代码更容易移植到另一个环境。

随处运行 –那要看情况。 Java的最初目标是在任何地方运行。 显然,由于Java虚拟机的function不同,所以无法在所有地方运行代码。 移动电话中的VM可能不会支持与运行银行应用程序的IBM大型机相同的库。 有两个问题需要注意。 首先,OSGi API不应该使用在所有环境中都不可用的类。 其次,如果bundle包含在执行环境中不可用的代码,它就不应该启动。 这两个问题都已经在OSGi规范中处理过了。

资料来源: http://www.osgi.org/Technology/WhyOSGi

我不太在意OSGi模块的热插拔性(至less目前)。 这是更强制的模块化。 在任何时候,classpath上都没有数百万的“公共”类可以很好的保护循环依赖:你必须真正考虑你的公共接口 – 不仅仅是Java语言结构“public”,而且就你的库而言/模块:什么(确切)是组件,你想提供给其他人? 什么(确切地说)是你真正需要实现你的function的接口(其他模块)?

这很好,热插拔与它,但我宁愿重新启动我的平常应用程序,而不是testing所有的热插拔组合…

  • 您可以类比地说,改变你的车的电机,而不closures它。
  • 您可以为客户定制复杂的系统。 看看Eclipse的强大function
  • 您可以重新使用整个组件。 比对象更好。
  • 您使用稳定的平台来开发基于组件的应用程序。 这个好处是巨大的。
  • 您可以使用黑匣子概念构build组件。 其他组件不需要知道隐藏的接口,他们只看到发布的接口。
  • 您可以在同一个系统中使用几个相同的组件,但在不同的版本中,不会影响应用程序。 OSGi解决了Jar Hell问题。
  • 借助OSGi,您可以开发构build具有CBDfunction的系统

有很多好处(我现在提醒这些),适用于所有使用Java的人。

编辑清晰。 OSGi页面给出了比我更好的简单答案

一个简单的答案:一个OSGi服务平台为合作的networking服务提供了一个标准化的,面向组件的计算环境。 这种架构大大降低了构build,维护和部署应用程序的整体复杂性。 OSGi服务平台提供了在各种networking设备上dynamic改变组合的function,无需重新启动。

在一个单一的应用程序结构中,比如说Eclipse IDE,当你安装一个新的插件时重新启动并不是一件大事。 完全使用OSGi实现,您应该能够在运行时添加插件,获得新的function,但不必重新启动eclipse。

再次,不是每天都有一件大事,小应用程序的使用。

但是,当你开始考虑多计算机分布式应用程序框架的时候,这就开始变得有趣了。 当关键系统必须具有100%的正常运行时间时,热切换组件或在运行时添加新function的function是非常有用的。 当然,目前有这样做的能力,但OSGi正试图将所有东西都捆绑到一个带有通用接口的漂亮的小框架中。

OSGi是否可以解决常见的问题,我不确定。 我的意思是,它可以,但是对于较简单的问题,开销可能不值得。 但是当你开始处理更大的,联网的应用程序的时候,这是需要考虑的事情。

有几件事让我对OSGi感到愤怒:

1)实现和它们的上下文加载器有很多怪癖,并且可能有些asynchronous(我们在汇合中使用felix)。 相比于纯粹的spring(没有DM),其中[main]几乎是同步运行的一切。

2)热负荷后类不相同。 比如说,你在hibernate时有一个tangosolcaching层。 它在OSGi范围之外充满了Fork.class。 你加载一个新的jar,而fork没有改变。 class[叉]!=class[叉]。 它也出现在序列化过程中,原因相同。

3)聚类。

你可以解决这些问题,但这是一个主要的重大难题,而且会让你的架构显得有缺陷。

对于那些广告热插拔.. OSGi的#1客户端? 蚀。 Eclipse在加载包后会做什么?

它重新启动。

如果基于Java的应用程序需要添加或删除模块(扩展应用程序的基本function),而不closuresJVM,则可以使用OSGI。 通常如果closuresJVM的成本更多,只是为了更新或增强function。

例如

  1. Eclipse :为插件提供安装,卸载,更新和相互依赖的平台。
  2. AEM :WCM应用程序,function更改将由业务驱动,无法承受停机维护时间。

注意 :Spring框架停止支持OSGI spring bundles,认为它是基于事务的应用程序或这些行中的某些点的不必要的复杂性。 我个人不认为OSGI,除非是绝对必要的,像build立一个平台这样的东西。

我还没有成为OSGi的“粉丝”…

我一直在“财富”100强企业中使用企业应用程序。 最近,我们使用的产品已经升级为OSGi实现。

开始本地cba部署… [2/18/14 8:47:23:727 EST] 00000347 CheckForOasis

最终部署,“下列软件包将被停顿,然后重新启动”[2/18/14 9:38:33:108 EST] 00000143 AriesApplicat I CWSAI0054I:作为应用程序更新操作的一部分

51分钟…每次代码更改…以前的版本(非OSGi)将在不到5分钟的时间内部署在较早的开发机器上。

在一台机器上有16个ram和40个免费的磁盘和Intel i5-3437U 1.9 GHz的CPU

这种升级的“好处”是作为改进(生产)部署而出售的 – 我们每年做大约4次的活动,每年可能进行2-4次小规模部署。 每天为15个人(QA和开发人员)增加45分钟,我无法想象有什么合理的。 在大型企业应用程序中,如果你的应用程序是一个核心应用程序,那么改变它是正确的(小的变化有潜在的深远影响 – 必须与整个企业的消费者进行沟通和计划),一个巨大的活动 – 错误的体系结构OSGi的。 如果您的应用程序不是企业应用程序 – 也就是说,每个消费者可以拥有自己定制的模块,可能会将自己的数据存储在自己的数据库中,并运行在托pipe许多应用程序的服务器上,那么可以查看OSGi。 至less,这是我迄今的经验。

它也被用来为移动端带来中间件和应用程序的附加可移植性。 例如,移动端可用于WinMo,Symbian,Android。 一旦与设备function集成发生,就可能分散。

OSGi至less可以让你思考模块化,代码重用,版本控制以及项目pipe理。

OSGi提供以下好处:

■基于Java的便携式安全执行环境

■服务pipe理系统,可用于跨服务套件注册和共享服务,并将服务提供商与服务使用者分离

■dynamic模块系统,可用于dynamic安装和卸载OSGi调用捆绑的Java模块

■轻量级和可扩展的解决scheme

其他人已经详细介绍了好处,我在此解释我已经看到或使用OSGi的实际使用情况。

  1. 在我们的一个应用程序中,我们基于事件的stream程和stream程是在基于OSGi平台的插件中定义的,所以明天如果某个客户想要不同的/额外的stream程,那么他只需要部​​署一个插件,从我们的控制台configuration他, 。
  2. 它用于部署不同的存储连接器,例如,假设我们已经有Oracle DB连接器,并且需要明天mongodb连接,然后编写一个新的连接器并部署它并通过控制台configuration详细信息,然后完成。 连接器的部署由OSGi插件框架处理。

OSGi使你的代码抛出NoClassDefFoundErrorClassNotFoundException没有明显的原因(最可能是因为你忘了导出一个包在OSGiconfiguration文件); 因为它有ClassLoaders它可以使你的类com.example.Foo不能被转换为com.example.Foo因为它实际上是由两个不同的类加载器加载的两个不同的类。 在安装Eclipse插件后,它可以使Eclipse启动到OSGi控制台。

对我来说,OSGi只增加了复杂性(因为它增加了一个思维模型,让我思考),因为例外而增加了烦恼; 我从来没有真正需要它“提供”的dynamic性。 这是侵入性的,因为它需要所有模块的OSGi包configuration; 这绝对不是简单的(在一个更大的项目中)。

由于我的经历不好,我倾向于远离那个怪物,非常感谢。 我宁愿忍受瓶子依赖地狱,因为这是比OSGi引入的类加载器更容易理解。