Apache Felix Framework启动和内嵌.docx
- 文档编号:28008041
- 上传时间:2023-07-07
- 格式:DOCX
- 页数:23
- 大小:22.30KB
Apache Felix Framework启动和内嵌.docx
《Apache Felix Framework启动和内嵌.docx》由会员分享,可在线阅读,更多相关《Apache Felix Framework启动和内嵌.docx(23页珍藏版)》请在冰豆网上搜索。
ApacheFelixFramework启动和内嵌
启动和内嵌ApacheFelixFramework
【本文档是Felix2.0.0及最终版本的启动介绍;它兼容Felix框架的旧版本。
】
简介
Felix很容易启动和嵌入到其他应用程序。
例如,Felix避免使用系统属性进行配置,因此可以在同一个虚拟机中启动多个Felix实例。
Felix也建立了多个单例工厂,如URLstreamhandler工厂。
其总体目标是在广泛的范围内使用框架。
OSGI启动和嵌入式API概述
Felix实现了org.apache.felix.framewor.Felix类。
作为OSGI规范4.2的一部分,OSGI启动和嵌入式API已经标准化。
框架需要实现org.osgi.framework.launch.Framework接口(继承了org.osgi.framework.Bundle接口)。
此接口提供了必要的信息启动和管理框架实例。
Bundel接口定义如下:
publicinterfaceBundle
{
BundleContextgetBundleContext();
longgetBundleId();
URLgetEntry(Stringname);
EnumerationgetEntryPaths(Stringpath);
EnumerationfindEntries(Stringpath,StringfilePattern,booleanrecurse);
DictionarygetHeaders();
DictionarygetHeaders(Stringlocale);
longgetLastModified();
StringgetLocation();
URLgetResource(Stringname);
EnumerationgetResources(Stringname)throwsIOException;
ServiceReference[]getRegisteredServices();
ServiceReference[]getServicesInUse();
intgetState();
StringgetSymbolicName();
VersiongetVersion();
booleanhasPermission(Objectobj);
ClassloadClass(Stringname)throwsClassNotFoundException;
voidstart()throwsBundleException;
voidstop()throwsBundleException;
voiduninstall()throwsBundleException;
voidupdate()throwsBundleException;
voidupdate(InputStreamis)throwsBundleException;
}
Framework接口定义如下:
publicinterfaceFrameworkextendsBundle
{
voidinit();
FrameworkEventwaitForStop(longtimeout);
}
实际构造框架实例,R4.2规范定义了FrameworkFactory接口:
publicinterfaceFrameworkFactory
{
FrameworknewFramework(Mapconfig);
}
可以使用框架工厂类配置和建立框架实例。
通过标准的META-INF/services获得。
建立和配置框架实例
可以使用工厂类构造和配置框架实例(或者直接实例化Felix类)。
配置表包含任意框架配置属性(见Felix框架配置属性集),不包含启动配置属性。
配置属性大小写敏感。
构造框架后不能再改变框架配置。
如果需要不同的配置,必须建立新的框架实例。
启动框架实例
使用start()方法启动框架实例。
如果init()方法没有先于start()方法调用,start()方法会调用init()。
2个方法执行完使框架处于不同状态。
●init()框架实例在Bundle.STARTINT状态。
●start()框架实例在Bundle.ACTIVE状态。
框架第一次建立时,还没有BundleContext时,必须执行inti方法,所以转换到Bundle.STARTINT状态前必须要建立他的上下文(通过Bundle.getBundleContext()),执行几个任务,例如:
安装bundles。
注意,Felix也提供了felix.systembundle.activators属性也起到相同的作用,但不是标准的。
init方法执行完毕,需要执行下列操作:
●使能事件处理器
●如果使能安全,安装安全管理器
●所有bundle缓存中的bundle具体化,设为Bundle.INSTALLED状态
●框架获得一个合法的BundelContext
●所有osgi服务可用(如:
PackageAdmi、StartLevel等)
●框架进入Bundle.STARTINT状态
调用start方法启动框架实例,如果init方法是手工调用的。
已经启动框架后调用inint和start方法没有任何效果。
停止框架实例
调用stop()方法将异步停止框架实例。
使用watiForStop()方法等待框架完成终止动作。
停止的框架处于Bundle.RESOLVED状态。
可以使用init/start重启框架。
启动框架
启动框剪相当简单,仅需要4步:
1、定义些配置属性
2、获得框架工厂类
3、使用工厂类(包含配置属性)建立框架实例
4、调用Framework.start()方法
实际上,自所有的属性都有了缺省值,第一步是可选的,除非建立一个自定义的启动器,如自动安装和启动bundle。
Felix启动器默认自动安装和启动bundle;查看用户手册获得更多Felix配置属性信息。
下面的章节描述如何启动Felix以及自定义启动。
标准的Felix启动器
标准的Felix启动器很简单,不打算解决每一种需求;相反着重解决规范的情景。
大多数特殊的启动要求将建立自定义的启动器。
下列main()方法代码描述了标准的启动器,每行注释将描述更多细节:
publicstaticvoidmain(String[]args)throwsException
{
//
(1)Checkforcommandlineargumentsandverifyusage.
StringbundleDir=null;
StringcacheDir=null;
booleanexpectBundleDir=false;
for(inti=0;i { if(args[i].equals(BUNDLE_DIR_SWITCH)) { expectBundleDir=true; } elseif(expectBundleDir) { bundleDir=args[i]; expectBundleDir=false; } else { cacheDir=args[i]; } } if((args.length>3)||(expectBundleDir&&bundleDir==null)) { System.out.println("Usage: [-b System.exit(0); } // (2)Loadsystemproperties. Main.loadSystemProperties(); //(3)Readconfigurationproperties. PropertiesconfigProps=Main.loadConfigProperties(); if(configProps==null) { System.err.println("No"+CONFIG_PROPERTIES_FILE_VALUE+"found."); configProps=newProperties(); } //(4)Copyframeworkpropertiesfromthesystemproperties. Main.copySystemProperties(configProps); //(5)Usethespecifiedauto-deploydirectoryoverdefault. if(bundleDir! =null) { configProps.setProperty(AutoProcessor.AUTO_DEPLOY_DIR_PROPERY,bundleDir); } //(6)Usethespecifiedbundlecachedirectoryoverdefault. if(cacheDir! =null) { configProps.setProperty(Constants.FRAMEWORK_STORAGE,cacheDir); } //(7)Addashutdownhooktocleanstoptheframework. StringenableHook=configProps.getProperty(SHUTDOWN_HOOK_PROP); if((enableHook==null)||! enableHook.equalsIgnoreCase("false")) { Runtime.getRuntime().addShutdownHook(newThread("FelixShutdownHook"){ publicvoidrun() { try { if(m_fwk! =null) { m_fwk.stop(); m_fwk.waitForStop(0); } } catch(Exceptionex) { System.err.println("Errorstoppingframework: "+ex); } } }); } try { //(8)Createaninstanceandinitializetheframework. FrameworkFactoryfactory=getFrameworkFactory(); m_fwk=factory.newFramework(configProps); m_fwk.init(); //(9)Usethesystembundlecontexttoprocesstheauto-deploy //andauto-install/auto-startproperties. AutoProcessor.process(configProps,m_fwk.getBundleContext()); //(10)Starttheframework. m_fwk.start(); //(11)WaitforframeworktostoptoexittheVM. m_fwk.waitForStop(0); System.exit(0); } catch(Exceptionex) { System.err.println("Couldnotcreateframework: "+ex); ex.printStackTrace(); System.exit(0); } } 一般,标准启动器很直接: 1、启动器设置auto-deply目录(使用-b选项)、使用1个目录设置bundle缓存路径,所以检查参数大于1个。 2、调入system.properties文件系统属性;这个文件典型的放在Felix安装目录下conf/中,也可以使用felix.system.properties系统属性配置。 此文件时标准的java属性文件,使用${ 属性代替方式支持嵌入,仅系统属性能使用代替方式。 3、调入config.properties文件中的配置信息,这个文件也放在conf/目录,也可以使用felix.config.properties系统属性配置。 此文件建立启动器的配置信息。 此文件也支持代替方式。 4、习惯上,任何系统属性拷贝到配置属性集里,很容易增加和覆盖config.properties文件中的属性。 5、如果启用了-b选项,将使用一个特定的auto-deploy目录,也可使用felix.auto.deploy.dir配置值。 6、如果使用了一个单一的命令行参数,将使用它设置org.osgi.framework.storage;相对与当前目录的路径。 除非设置了felix.cache.rootdir属性配置。 7、增加停止钩子,除非禁止钩子。 8、使用配置属性,通过FrameworkFactory建立框架实例,然后,初始化工厂实例;下面的自定义启动器示例描述了如何通过META-INF/services获得FrameworkFactory 9、调用org.apache.felix.main.AutoProcessor,自动部署auto-deploy目录的bundle,根据felix.auto.install和felix.auto.start属性自动安装或启动bundle。 10、调用waitForStop方法等待框架终止并退出虚拟机;这是必须的,因为框架永不会调用System.exit(),一些库(如,Swing)建立线程后不允许虚拟机退出。 框架知道调用start方法激活。 如果没有shellbundle安装启动的话,框架将悬挂运行,实际上,没有任何方式可以与它交互,shell仅提供了底层的交互。 自定义框架启动器 本节建立一个最小的启动器,演示一个最小需求、交互式的Felix启动器。 本示例使用标准的Gogoshellbundle进行交互,当然也能使用其他bundle。 本例项目结构如下: launcher/ lib/ org.apache.felix.main-3.0.0.jar bundle/ mand-0.6.0.jar org.apache.felix.gogo.runtime-0.6.0.jar org.apache.felix.gogo.shell-0.6.0.jar src/ example/ Main.java lib/目录包含Felixmainjar文件,也包含OSGI核心接口。 使用mainJAR文件可以重用缺省的启动器自动部署/自动启动配置属性处理器;如果不需要此功能,可以使用frameworJAR文件替换mainJAR文件。 bundle/目录包含shell服务和文本shell接口bundle,可以通过它与框剪交互。 注: 如果没有交互式bundle,框架将悬挂运行。 src/example/目录包含下面Main.java文件,是一个很简单的框架启动器: packageexample; importjava.io.*; importorg.osgi.framework.launch.*; importorg.apache.felix.main.AutoProcessor; publicclassMain { privatestaticFrameworkm_fwk=null; publicstaticvoidmain(String[]argv)throwsException { //Printwelcomebanner. System.out.println("\nWelcometoMyLauncher"); System.out.println("======================\n"); try { m_fwk=getFrameworkFactory().newFramework(null); m_fwk.init() AutoProcessor.process(null,m_fwk.getBundleContext()); m_fwk.start(); m_fwk.waitForStop(0); System.exit(0); } catch(Exceptionex) { System.err.println("Couldnotcreateframework: "+ex); ex.printStackTrace(); System.exit(-1); } } privatestaticFrameworkFactorygetFrameworkFactory()throwsException { URLurl=Main.class.getClassLoader().getResource( "META-INF/services/org.osgi.framework.launch.FrameworkFactory"); if(url! =null) { BufferedReaderbr=newBufferedReader(newInputStreamReader(url.openStream())); try { for(Strings=br.readLine();s! =null;s=br.readLine()) { s=s.trim(); //Trytoloadfirstnon-empty,non-commentedline. if((s.length()>0)&&(s.charAt(0)! ='#')) { return(FrameworkFactory)Class.forName(s).newInstance(); } } } finally { if(br! =null)br.close(); } } thrownewException("Couldnotfindframeworkfactory."); } } 启动器依赖AutoProcessor默认行为处理shellbundle自动部署。 这个简单通用的启动器提供了一个起点,如果Felix启动器不够用。 m_fwk=getFrameworkFactory().newFramework(null); m_fwk.init() 本步是获得框架工厂服务,使用它建立默认配置的框架实例,并调用intit方法初始化。 AutoProcessor.process(null,m_fwk.getBundleContext()); AutoProcessor自动部署在auto-deploy目录的bundle,并处理自动install/start。 如果是空配置,没有自动属性,auto-deploy目录是当前目录下的bundle目录。 当前,shellbundle将被安装。 m_fwk.start(); m_fwk.waitForStop(0); System.exit(0); 最后是启动框架,启动应用线程并等待框架终止,当应用线程调用System.exit(),虚拟机将退出。 privatestaticFrameworkFactorygetFrameworkFactory()throwsException { ... } 此方法查找META-INF/services资源获得工厂类。 如果使用Java6,可以使用JAE中的ServiceLoader简单获得工厂服务。 下列命令在项目根目录编译启动器: javac-d.-classpathlib/org.apache.felix.main-3.0.0.jarsrc/example/Main.java 执行这个命令后,example/目录在当前目录建立,包含生成的class文件。 下面的命令在项目根目录执行简单的启动: java-cp.: lib/org.apache.felix.main-3.0.0.jarsrc/example/Main.java 执行此命令后,“felix-cache”目录建立,包含缓存的bundle(是从bundle/目录安装的bundle) 嵌入Felix框架 把Felix嵌入一个宿主,是提供可扩展的机制(如: 插件系统)的简单办法。 嵌入Felix与上述描述类似,主要的不同是宿主想与框架实例和暴漏bundle/service交互。 这有些微妙的不同点。 本节描述宿主嵌入Felix的机制。 宿主/Felix交互 在上面启动框架时,Felix类接受felix.systembundle.activators配置属性(bundleactivator实例列表)。 bundleactivator实例提供了宿主与Felix框剪交互的方法。 每个activator实例实际变成了系统bundle的一部分。 这意味着列表中每个activator实例start/stop方法在系统bundle激活时都被分别调用。 每个activator实例提供了BundleContext对象,所以能与框架交互。 看看下面bundleactivator片段: publicclassHostActivatorimplementsBundleActivator { privateBundleContextm_context=null; publicvoidstart(BundleContextcontext) { m_context=context; } publicvoidstop(BundleContextcontext) { m_context=null; } publicBundle[]getBundles() { if(m_context! =null) { returnm_context.getBundles(); } returnnull; } } 现在可以嵌入Felix,下述片段演示了交互: publicclassHostApplication { privateHostActivatorm_activato
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Apache Felix Framework启动和内嵌 Framework 启动
![提示](https://static.bdocx.com/images/bang_tan.gif)