ApacheFelixFramework启动和内嵌Word格式文档下载.docx
《ApacheFelixFramework启动和内嵌Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《ApacheFelixFramework启动和内嵌Word格式文档下载.docx(21页珍藏版)》请在冰豆网上搜索。
![ApacheFelixFramework启动和内嵌Word格式文档下载.docx](https://file1.bdocx.com/fileroot1/2023-1/30/f96fc86b-09dc-40f3-8ac4-9eb6e985a632/f96fc86b-09dc-40f3-8ac4-9eb6e985a6321.gif)
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<
args.length;
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<
bundle-deploy-dir>
][<
bundle-cache-dir>
]"
);
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!
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!
m_fwk.stop();
m_fwk.waitForStop(0);
catch(Exceptionex)
Errorstoppingframework:
"
+ex);
});
//(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.
Couldnotcreateframework:
ex.printStackTrace();
一般,标准启动器很直接:
1、启动器设置auto-deply目录(使用-b选项)、使用1个目录设置bundle缓存路径,所以检查参数大于1个。
2、调入system.properties文件系统属性;
这个文件典型的放在Felix安装目录下conf/中,也可以使用felix.system.properties系统属性配置。
此文件时标准的java属性文件,使用${<
property-name>
}语法支持代替方式。
属性代替方式支持嵌入,仅系统属性能使用代替方式。
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.
\nWelcometoMyLauncher"
======================\n"
m_fwk=getFrameworkFactory().newFramework(null);
m_fwk.init()
AutoProcessor.process(null,m_fwk.getBundleContext());
System.exit(-1);
privatestaticFrameworkFactorygetFrameworkFactory()throwsException
URLurl=Main.class.getClassLoader().getResource(
META-INF/services/org.osgi.framework.launch.FrameworkFactory"
if(url!
BufferedReaderbr=newBufferedReader(newInputStreamReader(url.openStream()));
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将被安装。
最后是启动框架,启动应用线程并等待框架终止,当应用线程调用System.exit(),虚拟机将退出。
...
此方法查找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!
returnm_context.getBundles();
returnnull;
现在可以嵌入Felix,下述片段演示了交互:
publicclassHostApplication
privateHostActivatorm_activator=null;
privateFeli