OSGI

Posted llguanli

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OSGI相关的知识,希望对你有一定的参考价值。


?该规范和核心部分是一个框架?,当中定义了应用程序的生命周期模式和服务注冊。基于这个框架定义了大量的OSGi服务:?日志配置管理、偏好,HTTP(执行servlet)、XML分析、设备訪问、软件包管理、许可管理、星级、用户管理、IO连接、连线管理、Jini和?UPnP

这个框架实现了一个优雅、完整和动态的php?

title=%E7%BB%84%E4%BB%B6%E6%A8%A1%E5%9E%8B&action=edit&redlink=1" title="组件模型(页面不存在)">组件模型。应用程序(称为bundle)无需又一次引导能够被远程安装、启动、升级和卸载(当中Java包/类的管理被具体定义)。

API中还定义了执行远程下载管理政策的生命周期管理服务注冊同意bundles去检測新服务和取消的服务。然后对应配合。

OSGi原先关注于服务网关。事实上可用于多个方面。如今OSGi规范已经用于从移动电话到开源的Eclipse(当中包含了与IBMOSGi框架SMF兼容的开源版本号)。?OSGi服务平台的应用包含:服务网关、?汽车移动电话、?工业自己主动化建筑物自己主动化、?PDA?网格计算娱乐(如iPronto)、和?IDE

OSGi规范是由成员通过公开的程序开发,对公众免费而且没有许可证限制。

可是OSGi?Alliance兼容性程序仅仅对成员开放,眼下有12个兼容的实现

2003Eclipse选择OSGi作为其插件的底层执行时架构。Equinox?project对该理念进行了实验。20046月在Eclipse3?R3中公布。ProSyst是面向OSGi开发人员的Eclipse插件。

?

OSGI?里面有几个核心类:BundleContext,?Bundle,?ServiceRegistration,?ServiceReference

?

http://blog.csdn.net/teamlet/article/category/297017

关于OSGI的启动包含一个启动jar包和一个配置文件

Equinox\Configuration\Config.ini中放置的是启动信息

eclipse.ignoreApp=true

osgi.noShutdown=true

osgi.framework.activeThreadType=normal

osgi.bundles=./[email protected]:start,./[email protected]:start

?

Equinox\org.eclipse.osgi_3.5.0.v20090520.jar?

假设将该Jar放在在Cosgi-dev下,那么在命令提示符下进入C:/osgi-dev?文件夹,执行以下命令:

>?java?-console?-jar?org.eclipse.osgi_3.3.1.R33x_v20070828.jar

几秒钟,osgi>提示符显示出来。

以下为一个sh脚本启动Osgi

#!/bin/sh

#resl=`ps?-ef|grep?yuewang|grep?-v?grep`

resl=`ps?-ef|grep?org.eclipse.osgi_3.5.0.v20090520.jar|grep?-v?grep`

flag=0

for?i?in?$resl

do

??#echo?$i

??if?[?!?-z?$i?];?then

????flag=1

??fi

done

?

if?[?$flag?==?0?];?then

echo?"starting?SDMExpert"

cd?/etc/sdme

java?-Dlog4j.configuration=file:///etc/sdme/Properties/log4j.xml?-DSDMExpert.corbaTrace=off?

?????-Djacorb.connection.client.idle_timeout=600000?-Djacorb.connection.client.pending_reply_timeout=300000?

?-Djacorb.poa.queue_wait=on?-Djacorb.net.socket_factory.port.max=3000?

?-Dlogconsole?-jar?/usr/sdme/bin/org.eclipse.osgi_3.5.0.v20090520.jar?

?-configuration?/local/sdme/equinox?-clean?&

echo?"SDMExpert?started?now"

else

echo?"?sdmexpert?already?started"

fi

exit

?

?

?

可执行Java

?

http://www.ibm.com/developerworks/cn/opensource/os-ecl-osgibdev/

OSGi?规范简介

OSGi?联盟建立于?1999?年,是一个非赢利机构。旨在建立一个开放的服务规范。

OSGi?规范为网络服务定义了一个标准的、面向组件的计算环境,它最初的目的就是为各种嵌入式设备提供通用的软件执行平台。屏蔽设备操作系统与硬件差别的中间件平台。通过这个平台。能够对不同软件商提供的应用(OSGi?中称为?Bundle)进行组件的生命周期管理的能力,如应用组件能够从执行中被安装、升级或者移除而不须要中断设备的操作,应用组件能够动态的发现和使用其它库或者应用程序。

因为?OSGi?技术具有服务组件模块化、动态载入应用等长处,正被越来越多的领域关注,如嵌入设备制造业、汽车制造业、企业应用等。眼下,OSGi?联盟公布的最新的?OSGi?服务规范为?4.0。读者能够查阅參考资料了解具体信息。

回页首

OSGi?体系结构

OSGi?的体系架构是基于插件式的软件结构,包含一个?OSGi?框架和一系列插件。在?OSGi中,插件称为?Bundle,当中,OSGi?框架规范是?OSGi?规范的核心部分,它提供了一个通用的、安全可管理的?Java?框架,通过这个框架。能够支持?Bundle?服务应用的部署和扩展。Bundle?之间能够通过?Import?Package?和?Require-Bundle?来共享?Java?类。在?OSGi?服务平台中。用户通过开发?Bundle?来提供须要的功能。这些?Bundle?能够动态载入和卸载,或者依据须要远程下载和升级。OSGi?体系结构图如图?1?所看到的:


图示1?OSGi?体系结构
?

当中:

Execution?Environment

Bundle?应用所倚赖执行的?Java?执行环境。如?J2SE-1.4CDC-1.0?等都是可用的执行环境。

Modules

模块层定义了?Bundle?应用的载入策略。OSGi?框架是一个健壮而且严格定义的类载入模型。在大多数?Java?应用中。通常仅仅有一个单独的?ClassPath,它包含了全部的?Java?类文件和资源文件。OSGi基于Java技术。对于每一个实现了?BundleActivator?接口的?Bundle?应用,为它生成一个单独的?ClassLoader,使得?Bundle?应用的组织更加模块化。

Life?Cycle

生命周期层能够动态地对?Bundle?进行安装install、启动(start)、停止(stop、升级和卸载等操作。该层基于模块层。提供了一组?API?来控制?Bundle?应用的执行时操作。

Registers?the?specified?service?object?with?the?specified?properties?under?the?specified?class?names?into?the?Framework.?A?ServiceRegistration?object?is?returned.?The?ServiceRegistration?object?is?for?the?private?use?of?the?bundle?registering?the?service?and?should?not?be?shared?with?other?bundles.?The?registering?bundle?is?defined?to?be?the?context?bundle.?Other?bundles?can?locate?the?service?by?using?either?the

{getServiceReference}?method.

The?ServiceRegistration?object?may?be?used?to?update?the?properties?of?the?service?or?to?unregister?the?service.

Service?Registry?和?Services

servR?=?context.registerService(IBundleInstallerService.class.getName(),?installer,?null);

servR.unregister();

?

?

为啥要使用ServiceRegistrationServiceReference,我的观点是统一的接口进行管理和为了性能。使用Reference而不是对象本身,方面能够节省内存一方面能够提高性能。

BundleContext.registerService得到ServiceRegistration,通过ServiceRegistrationgetReference得到ServiceReference。通过ServiceReferencegetService得到对象本身。

注冊时使用的Properties文件的Properties信息来源于bundle中的Manifest.xml文件。

?

OSGi?服务层定义了一个集成在生命周期层中的动态协作模型,是一个公布、动态寻找、绑定的服务模型。一个服务一般是一个?Java?对象实现了特定的服务接口,而且通过服务注冊,被绑定到?OSGi?的执行环境中。

Bundle?应用能够注冊公布服务。动态绑定服务,而且在服务注冊状态改变时,能够接受到事件消息等。

Security

OSGi?的安全管理是基于?Java2?安全体系的,贯穿在?OSGi?平台的全部层中。它能够对部署在?OSGi?执行环境中的?Bundle?应用进行具体的管理控制。

回页首

Bundle?生命周期的状态

在一个动态扩展的?OSGi?环境中,OSGi?框架管理?Bundle?的安装和更新。同一时候也管理?Bundle?和服务之间的依赖关系。

一个?Bundle?可能处于以下六个状态,关于Bundle的生命周期能够通过Bundle.getState()方法得到。如图?2?所看到的:


图示?2?Bundle?状态图
?

INSTALLED:安装完毕,本地资源成功载入:?BundleContext.installBundle(location)方法,成功后返回一个bundle对象。

?

RESOLVED:依赖关系包含classpathpackage满足。这个状态意味该Bundle要么已经准备好执行,要么是被停止了。体如今代码上例如以下:通过getBundlesRequirement方法得到全部bundleBundleRequirement,这种方法中主要是对Require-Bundle里面的全部Bundle进行解析放到List中。再通过matchBundleAndRequirement对Bundle的依赖进行验证,满足后Bundle的状态就变为Resolved状态了。

private?HashMap<Bundle,?ArrayList<BundleRequirement>>?getBundlesRequirement(ArrayList<Bundle>?bundles)?{

HashMap<Bundle,?ArrayList<BundleRequirement>>?bundleTree?=?new?LinkedHashMap<Bundle,?ArrayList<BundleRequirement>>();

for?(Bundle?bdl?:?bundles)?{

ArrayList<BundleRequirement>?req?=?BundleUtil.getRequirement(bdl);

bundleTree.put(bdl,?req);

}

return?bundleTree;

}

public?HashMap<Bundle,?ArrayList<Bundle>>?matchBundleAndRequirement(HashMap<Bundle,?ArrayList<BundleRequirement>>?bundlesRequirement)?{

HashMap<Bundle,?ArrayList<Bundle>>?bundleTree?=?new?HashMap<Bundle,?ArrayList<Bundle>>();

for?(Bundle?key?:?bundlesRequirement.keySet())?{

ArrayList<BundleRequirement>?requirement?=?bundlesRequirement.get(key);

?

ArrayList<Bundle>?list?=?new?ArrayList<Bundle>();

for?(BundleRequirement?req?:?requirement)?{

for?(Bundle?candidate?:?bundlesRequirement.keySet())?{

if?(req.satisfyRequirement(candidate))?{

list.add(candidate);

}

}

}

bundleTree.put(key,?list);

}

return?bundleTree;

}

?

STARTINGBundle正在被启动,BundleActivatorstart()方法已经被调用可是还没有返回。

?

STOPPINGBundle正在被停止,BundleActivatorstop()方法已经被调用可是还没有返回。

?

ACTIVEBundle?被成功启动而且在执行。

?

UNINSTALLEDbundle被卸载而且无法进入其它状态。

?

Bundle接口定义了getState()方法来返回Bundle的状态。

回页首

OSGi?标准服务

在?OSGi?平台之上。OSGi?联盟定义了非常多服务。服务是由一个?Java?Interface?来定义的。Bundle?能够实现这个接口而且把服务注冊到服务注冊表中去,用户能够从注冊表中找到须要的服务来使用,而且能够响应特定服务的状态改变,如服务注冊和服务取消。以下简介一下?OSGi?Release?4?的一些主要服务。OSGi?框架提供了权限管理服务,包管理服务和最初载入系统服务。这些服务是?OSGi?框架的一部分而且管理着?OSGi?框架的运作。

Permission?Admin?Service:权限管理是指?Bundle?是否许可其它的?Bundle?的代码。

当前的或者其它的?Bundle?的权限能够通过这个服务来操作,一旦被设定权限,立即就生效。

?Package?Admin?ServiceBundle?之间能够共享包内的?Java?类和资源,bundle?的更新可能须要?OSGi?框架又一次解析?Bundle?之间的依赖关系,这个服务提供了?OSGi?服务平台中包的共享状态信息。

Start?Level?ServiceStart?Level是指一些在特定Bundle起动之前必须执行或者初始化的一系列?bundleStart?Lever?Service?能够设置当前OSGi服务框架初始的Start?Level。而且能够指定和查询特定BundleStart?Level

回页首

使用?Eclipse?开发?Bundle?应用

Equinox?框架是?Eclipse?组织基于?OSGi?Release?4?的一个实现框架,它实现了?OSGi?规范的核心框架和很多标准框架服务的实现。关于Equinox项目的具体信息,请查阅參考资料信息。在本文中,我们使用?Eclipse?3.2?平台开发两个基于?OSGi?的?Bundle?应用。当中第一个?Bundle?应用声明、实现并注冊了一个姓名查询服务,用于推断所给姓名是否在已定义的查询列表中;第二个?Bundle?应用查询并引用第一个?Bundle?应用所注冊的姓名查询服务,假设用户所给的姓名包含在查询列表中,将返回正确的信息。最后。将开发的?Bundle应用部署的?Equinox?OSGi?框架中。用户能够在?OSGi?控制命令行中输入命令来查询关于框架和?Bundle?应用的具体信息。读者能够从參考资料中获得本文?Bundle?应用的源码。

(1)创建?Plug-in?Project,在?Eclipse?3.2?开发环境中,从菜单条选择?File?>?New?>?Project...?,打开?New?Project?向导,能够看到有Plug-in?Project创建向导。创建一个Plug-in?项目。项目名为?example?的?Bundle?应用,该应用实现并注冊了一个姓名查询服务,实现了?BundleActivator?接口。选择?Equinox?框架作为?Bundle?应用执行的?OSGi?服务平台。


图示?3?Plug-in?项目向导
?

(2)实现OSGi服务通常须要两个步骤。首先定义所提供服务的接口,然后实现这个服务接口。在本例中,我们创建一个姓名查询服务用来查询所给姓名是否有效。首先定义姓名查询接口NameService.java。以下是该接口的源码:


NameService?Interface?源码

package?example.service;

/**

?*?A?simple?service?interface?that?defines?a?name?service.

?*?A?name?service?simply?verifies?the?existence?of?a?Name.

**/

public?interface?NameService?{

/**

?????*?Check?for?the?existence?of?a?Name.

?????*[email protected]?name?the?Name?to?be?checked.

?????*[email protected]?true?if?the?Name?is?in?the?list,

?????*?????????false?otherwise.

????**/

public?boolean?checkName(String?name);

}


该服务接口非常easy,仅仅包含一个须要实现的方法。

为了将服务接口和服务实现相分离,方便其它?Bundle?引用该服务。我们通常须要将该服务接口单独放在一个包内,本例中,存放NameService.java?接口的?Java?包为?example.service。接下来,须要实现?NameService?接口,而且注冊该服务。在本例中,我们用内部类实现了该接口,以下是该?Bundle?应用的部分源码。


Example?Bundle部分源码

public?void?start(BundleContext?context)?throws?Exception?{

Properties?props?=?new?Properties();

props.put("ClassRoom",?"ClassOne");

context.registerService(NameService.class.getName(),?new?NameImpl(),

props);

}

private?static?class?NameImpl?implements?NameService?{

//?The?set?of?names?contained?in?the?arrays.

String[]?m_name?=?{?"Marry",?"John",?"David",?"Rachel",?"Ross"?};

/**

?*?Implements?NameService.checkName().?Determines?if?the?passed?name?is

?*?contained?in?the?Array.

?*?

?*[email protected]?name

?*????????????the?name?to?be?checked.

?*[email protected]?true?if?the?name?is?in?the?Array,?false?otherwise.

?*/

public?boolean?checkName(String?name)?{

//?This?is?very?inefficient

for?(int?i?=?0;?i?<?m_name.length;?i++)?{

if?(m_name[i].equals(name))?{

return?true;

}

}

return?false;

}

}?


start()方法中,利用BundleContext注冊一个姓名查询服务,而且为该服务设置相关属性以便服务查询。在实现姓名查询服务时。我们简单定义了一个静态数组用于存放有效的姓名信息。

(3)定义Bundle描写叙述文件MANIFEST.MFBundle应用exampleMANIFEST.MF文件例如以下:


MANIFEST.MF文件信息

Manifest-Version:?1.0

Bundle-ManifestVersion:?2

Bundle-Name:?Example?Bundle

Bundle-SymbolicName:?example

Bundle-Version:?1.0.0

Bundle-Activator:?example.osgi.Activator

Bundle-Localization:?plugin

Import-Package:?org.osgi.framework;version="1.3.0"

Export-Package:?example.service


当中。Bundle-Activator属性指明了实现BundleActivator接口的类,该类用来启动和停止Bundle应用。

Export-Package属性指定了该Bundle输出的共享包,该属性能够使其它的Bundle应用引用我们所定义的服务接口。

(4)创建项目名为exampleClientBundle应用,该应用在OSGi平台上查寻并引用example?Bundle应用已经注冊的姓名查询服务,然后从标准输入读入用户所输入的姓名信息。推断所输入姓名是否有效。

exampleClient应用的部分源码例如以下。读者可从參考资料中获得完整源码。


ExampleClient?Bundle部分源码

public?void?start(BundleContext?context)?throws?Exception?{

ServiceReference[]?refs?=?context.getServiceReferences(

NameService.class.getName(),?"(ClassRoom=*)");

if?(refs?!=?null)?{

try?{

System.out.println("Enter?a?blank?line?to?exit.");

BufferedReader?in?=?new?BufferedReader(new?InputStreamReader(

System.in));

String?name?=?"";

//?Loop?endlessly.

while?(true)?{

//?Ask?the?user?to?enter?a?name.

System.out.print("Enter?a?Name:?");

name?=?in.readLine();

//?If?the?user?entered?a?blank?line,?then

//?exit?the?loop.

if?(name.length()?==?0)?{

break;

}

//?First,?get?a?name?service?and?then?check

//?if?the?name?is?correct.

NameService?nameservice?=?(NameService)?context

.getService(refs[0]);

if?(nameservice.checkName(name))?{

System.out.println("The?Name?is?Correct.");

}?else?{

System.out.println("The?Name?is?Incorrect.");

}

//?Unget?the?name?service.

context.ungetService(refs[0]);

}

}?catch?(IOException?ex)?{

}

}?else?{

System.out.println("Couldn‘t?find?any?name?service...");

}

}

?

回页首

Bundle的部署及执行

Eclipse平台中,选择File-->Export...菜单,将开发的exampleexampleClient两个Bundle应用导出成Jar文件,以便将它们部署到OSGi服务平台中。选择将要执行的Bundle应用,鼠标右键点击。在弹出菜单中。选择Run?AS-->Equinox?FrameWork来启动OSGi服务平台

Equinox启动配置控制台中。能够为Bundle应用设置默认的Start?LevelBundle应用是否须要自己主动启动等选项。在本例中,为了解说怎样安装及启动Bundle应用,仅仅将example?Bundle应用设为自己主动启动。而exampleClient?Bundle应用须要我们用命令安装及启动。

OSGi?Equinox?FrameWork启动后,在OSGi控制命令台中输入ss命令,能够查看OSGi服务平台中已经安装的Bundle应用信息及其状态。

如图4所看到的,能够看到当前OSGi服务平台中有两个Bundle处于Active状态,当中。system.bundle_3.2.0.v20060328OSGi框架的系统Bundle,而example_1.0.0为注冊姓名查询服务的Bundle应用。1.0.0Bundle应用的版本号号。


图示4?Bundle信息查询
?

OSGi控制命令台中利用install命令安装exampleClient?Bundle应用,用ss命令查看安装后的Bundle应用信息及其状态。

如图5所看到的:


图示5?安装Bundle
?

OSGi控制命令台中利用start命令安装exampleClient?Bundle应用,用户可输入姓名,利用姓名查询服务来推断所输入姓名是否有效。用ss命令查看启动后的Bundle应用信息及其状态。如图6所看到的:


图示6?启动Bundle
?

用户在在OSGi控制命令台中,可利用stop命令来停止指定的Bundle应用。close命令用来停止并退出OSGi控制命令台。关于OSGi?Equinox?FrameWork控制台命令的具体信息。可查看參考资料。

回页首

总结

OSGi服务框架提供了开放的、面向服务的、易于部署的编程模型,在构件面向服务为中心的企业应用的过程中。OSGi?技术正发挥越来越关键的数据。眼下。Eclipse?3.2?体系架构是參照OSGi实现的,Equinox框架是?Eclipse?组织基于OSGi?Release?4?的一个实现框架。它实现了OSGi?规范的核心框架和很多标准框架服务。

在本文中。我们利用Eclipse?平台开发了两个Bundle应用,而且在Bundle应用中,声明、实现、注冊并引用了一个简单的服务,最后,将Bundle应用部署到Equinox?OSGi服务框架中。

通过本文。读者能够了解怎样开发和部署基于OSGi规范的Bundle应用。

?

以上是关于OSGI的主要内容,如果未能解决你的问题,请参考以下文章