ApacheFelixFramework启动和内嵌.docx

上传人:b****6 文档编号:8364715 上传时间:2023-01-30 格式:DOCX 页数:21 大小:22.30KB
下载 相关 举报
ApacheFelixFramework启动和内嵌.docx_第1页
第1页 / 共21页
ApacheFelixFramework启动和内嵌.docx_第2页
第2页 / 共21页
ApacheFelixFramework启动和内嵌.docx_第3页
第3页 / 共21页
ApacheFelixFramework启动和内嵌.docx_第4页
第4页 / 共21页
ApacheFelixFramework启动和内嵌.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

ApacheFelixFramework启动和内嵌.docx

《ApacheFelixFramework启动和内嵌.docx》由会员分享,可在线阅读,更多相关《ApacheFelixFramework启动和内嵌.docx(21页珍藏版)》请在冰豆网上搜索。

ApacheFelixFramework启动和内嵌.docx

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_activator=null;

privateFeli

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 教学研究 > 教学案例设计

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1