




已阅读5页,还剩8页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
启动和内嵌Apache Felix Framework【本文档是Felix2.0.0及最终版本的启动介绍;它兼容Felix框架的旧版本。】简介Felix很容易启动和嵌入到其他应用程序。例如,Felix避免使用系统属性进行配置,因此可以在同一个虚拟机中启动多个Felix实例。Felix也建立了多个单例工厂,如URL stream handler工厂。其总体目标是在广泛的范围内使用框架。OSGI启动和嵌入式API概述Felix实现了org.apache.felix.framewor.Felix类。作为OSGI规范4.2的一部分,OSGI启动和嵌入式API已经标准化。框架需要实现org.osgi.framework.launch.Framework接口(继承了org.osgi.framework.Bundle接口)。此接口提供了必要的信息启动和管理框架实例。Bundel接口定义如下:public interface Bundle BundleContext getBundleContext(); long getBundleId(); URL getEntry(String name); Enumeration getEntryPaths(String path); Enumeration findEntries(String path, String filePattern, boolean recurse); Dictionary getHeaders(); Dictionary getHeaders(String locale); long getLastModified(); String getLocation(); URL getResource(String name); Enumeration getResources(String name) throws IOException; ServiceReference getRegisteredServices(); ServiceReference getServicesInUse(); int getState(); String getSymbolicName(); Version getVersion(); boolean hasPermission(Object obj); Class loadClass(String name) throws ClassNotFoundException; void start() throws BundleException; void stop() throws BundleException; void uninstall() throws BundleException; void update() throws BundleException; void update(InputStream is) throws BundleException;Framework接口定义如下:public interface Framework extends Bundle void init(); FrameworkEvent waitForStop(long timeout);实际构造框架实例,R4.2规范定义了FrameworkFactory接口:public interface FrameworkFactory Framework newFramework(Map config);可以使用框架工厂类配置和建立框架实例。通过标准的 META-INF/services获得。建立和配置框架实例可以使用工厂类构造和配置框架实例(或者直接实例化Felix类)。配置表包含任意框架配置属性(见Felix框架配置属性集),不包含启动配置属性。配置属性大小写敏感。构造框架后不能再改变框架配置。如果需要不同的配置,必须建立新的框架实例。启动框架实例使用start()方法启动框架实例。如果init()方法没有先于start()方法调用,start()方法会调用init()。2个方法执行完使框架处于不同状态。l init() 框架实例在 Bundle.STARTINT状态。l start() 框架实例在Bundle.ACTIVE状态。框架第一次建立时,还没有BundleContext时,必须执行inti方法,所以转换到Bundle.STARTINT状态前必须要建立他的上下文(通过Bundle.getBundleContext(),执行几个任务,例如:安装bundles。注意,Felix也提供了felix.systembundle.activators属性也起到相同的作用,但不是标准的。init方法执行完毕,需要执行下列操作:l 使能事件处理器l 如果使能安全,安装安全管理器l 所有bundle缓存中的bundle具体化,设为Bundle.INSTALLED状态l 框架获得一个合法的BundelContextl 所有osgi服务可用(如:PackageAdmi、StartLevel等)l 框架进入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()方法代码描述了标准的启动器,每行注释将描述更多细节:public static void main(String args) throws Exception / (1) Check for command line arguments and verify usage. String bundleDir = null; String cacheDir = null; boolean expectBundleDir = false; for (int i = 0; i 3) | (expectBundleDir & bundleDir = null) System.out.println(Usage: -b ); System.exit(0); / (2) Load system properties. Main.loadSystemProperties(); / (3) Read configuration properties. Properties configProps = Main.loadConfigProperties(); if (configProps = null) System.err.println(No + CONFIG_PROPERTIES_FILE_VALUE + found.); configProps = new Properties(); / (4) Copy framework properties from the system properties. Main.copySystemProperties(configProps); / (5) Use the specified auto-deploy directory over default. if (bundleDir != null) configProps.setProperty(AutoProcessor.AUTO_DEPLOY_DIR_PROPERY, bundleDir); / (6) Use the specified bundle cache directory over default. if (cacheDir != null) configProps.setProperty(Constants.FRAMEWORK_STORAGE, cacheDir); / (7) Add a shutdown hook to clean stop the framework. String enableHook = configProps.getProperty(SHUTDOWN_HOOK_PROP); if (enableHook = null) | !enableHook.equalsIgnoreCase(false) Runtime.getRuntime().addShutdownHook(new Thread(Felix Shutdown Hook) public void run() try if (m_fwk != null) m_fwk.stop(); m_fwk.waitForStop(0); catch (Exception ex) System.err.println(Error stopping framework: + ex); ); try / (8) Create an instance and initialize the framework. FrameworkFactory factory = getFrameworkFactory(); m_fwk = factory.newFramework(configProps); m_fwk.init(); / (9) Use the system bundle context to process the auto-deploy / and auto-install/auto-start properties. AutoPcess(configProps, m_fwk.getBundleContext(); / (10) Start the framework. m_fwk.start(); / (11) Wait for framework to stop to exit the VM. m_fwk.waitForStop(0); System.exit(0); catch (Exception ex) System.err.println(Could not create framework: + ex); ex.printStackTrace(); System.exit(0); 一般,标准启动器很直接:1、 启动器设置auto-deply目录(使用-b选项)、使用1个目录设置bundle缓存路径,所以检查参数大于1个。2、 调入perties文件系统属性;这个文件典型的放在Felix安装目录下conf/中,也可以使用perties系统属性配置。此文件时标准的java属性文件,使用$语法支持代替方式。属性代替方式支持嵌入,仅系统属性能使用代替方式。3、 调入perties文件中的配置信息,这个文件也放在conf/目录,也可以使用perties系统属性配置。此文件建立启动器的配置信息。此文件也支持代替方式。4、 习惯上,任何系统属性拷贝到配置属性集里,很容易增加和覆盖perties文件中的属性。5、 如果启用了-b选项,将使用一个特定的auto-deploy目录,也可使用felix.auto.deploy.dir配置值。6、 如果使用了一个单一的命令行参数,将使用它设置org.osgi.framework.storage;相对与当前目录的路径。除非设置了felix.cache.rootdir属性配置。7、 增加停止钩子,除非禁止钩子。8、 使用配置属性,通过FrameworkFactory建立框架实例,然后,初始化工厂实例;下面的自定义启动器示例描述了如何通过META-INF/services获得FrameworkFactory9、 调用org.apache.felix.main.AutoProcessor,自动部署auto-deploy目录的bundle,根据felix.auto.install和felix.auto.start属性自动安装或启动bundle。10、 调用waitForStop方法等待框架终止并退出虚拟机;这是必须的,因为框架永不会调用System.exit(),一些库(如,Swing)建立线程后不允许虚拟机退出。框架知道调用start方法激活。如果没有shell bundle安装启动的话,框架将悬挂运行,实际上,没有任何方式可以与它交互,shell仅提供了底层的交互。自定义框架启动器本节建立一个最小的启动器,演示一个最小需求、交互式的Felix启动器。本示例使用标准的Gogo shell bundle进行交互,当然也能使用其他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.javalib/目录包含Felix main jar文件,也包含OSGI核心接口。使用main JAR文件可以重用缺省的启动器自动部署/自动启动配置属性处理器;如果不需要此功能,可以使用framewor JAR文件替换main JAR文件。bundle/目录包含shell服务和文本shell接口bundle,可以通过它与框剪交互。注:如果没有交互式bundle,框架将悬挂运行。src/example/目录包含下面Main.java文件,是一个很简单的框架启动器:package example;import java.io.*;import org.osgi.framework.launch.*;import org.apache.felix.main.AutoProcessor;public class Main private static Framework m_fwk = null; public static void main(String argv) throws Exception / Print welcome banner. System.out.println(nWelcome to My Launcher); System.out.println(=n); try m_fwk = getFrameworkFactory().newFramework(null); m_fwk.init() AutoPcess(null, m_fwk.getBundleContext(); m_fwk.start(); m_fwk.waitForStop(0); System.exit(0); catch (Exception ex) System.err.println(Could not create framework: + ex); ex.printStackTrace(); System.exit(-1); private static FrameworkFactory getFrameworkFactory() throws Exception URL url = Main.class.getClassLoader().getResource( META-INF/services/org.osgi.framework.launch.FrameworkFactory); if (url != null) BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream(); try for (String s = br.readLine(); s != null; s = br.readLine() s = s.trim(); / Try to load first non-empty, non-commented line. if (s.length() 0) & (s.charAt(0) != #) return (FrameworkFactory) Class.forName(s).newInstance(); finally if (br != null) br.close(); throw new Exception(Could not find framework factory.); 启动器依赖AutoProcessor默认行为处理shell bundle自动部署。这个简单通用的启动器提供了一个起点,如果Felix启动器不够用。m_fwk = getFrameworkFactory().newFramework(null);m_fwk.init()本步是获得框架工厂服务,使用它建立默认配置的框架实例,并调用intit方法初始化。AutoPcess(null, m_fwk.getBundleContext();AutoProcessor自动部署在auto-deploy目录的bundle,并处理自动install/start。如果是空配置,没有自动属性,auto-deploy目录是当前目录下的bundle目录。当前,shell bundle将被安装。 m_fwk.start(); m_fwk.waitForStop(0); System.exit(0);最后是启动框架,启动应用线程并等待框架终止,当应用线程调用System.exit(),虚拟机将退出。 private static FrameworkFactory getFrameworkFactory() throws Exception . 此方法查找META-INF/services资源获得工厂类。如果使用Java 6,可以使用JAE中的ServiceLoader简单获得工厂服务。下列命令在项目根目录编译启动器:javac -d . -classpath lib/org.apache.felix.main-3.0.0.jar src/example/Main.java执行这个命令后,example/目录在当前目录建立,包含生成的class文件。下面的命令在项目根目录执行简单的启动:java -cp .:lib/org.apache.felix.main-3.0.0.jar src/example/Main.java执行此命令后,“felix-cache”目录建立,包含缓存的bundle(是从bundle/目录安装的bundle)嵌入Felix框架把Felix嵌入一个宿主,是提供可扩展的机制(如:插件系统)的简单办法。嵌入Felix与上述描述类似,主要的不同是宿主想与框架实例和暴漏bundle/service交互。这有些微妙的不同点。本节描述宿主嵌入Felix的机制。宿主/Felix交互在上面启动框架时,Felix类接受felix.systembundle.activators配置属性(bundle activator实例列表)。bundle activator实例提供了宿主与Felix框剪交互的方法。每个activator实例实际变成了系统bundle的一部分。这意味着列表中每个activator实例start/stop方法在系统bundle激活时都被分别调用。每个activator实例提供了BundleContext对象,所以能与框架交互。看看下面bundle activator片段:public class HostActivator implements BundleActivator private BundleContext m_context = null; public void start(BundleContext context) m_context = context; public void stop(BundleContext context) m_context = null; public Bundle getBundles() if (m_context != null) return m_context.getBundles(); return null; 现在可以嵌入Felix,下述片段演示了交互:public class HostApplication private HostActivator m_activator = null; private Felix m_felix = null; public HostApplication() / Create a configuration property map. Map config = new HashMap(); / Create host activator; m_activator = new HostActivator(); List list = new ArrayList(); list.add(m_activator); configMap.put(FelixConstants.SYSTEMBUNDLE_ACTIVATORS_PROP, list); try / Now create an instance of the framework with / our configuration properties. m_felix = new Felix(config); / Now start Felix instance. m_felix.start(); catch (Exception ex) System.err.println(Could not create framework: + ex); ex.printStackTrace(); public Bundle getInstalledBundles() / Use the system bundle activator to gain external / access to the set of installed bundles. return m_activator.getBundles(); public void shutdownApplication() / Shut down the felix framework when stopping the / host application. m_felix.stop(); m_felix.waitForStop(0); 注意HostApplication.getInstalledBundles()方法使用activator实例访问系统bundle上下文与Felix交互。提供宿主服务宿主提供服务给嵌入Felix的bundle。提供宿主服务给bundle,实际上是宿主与bundle必须使用同样的服务类定义。而宿主不能导入bundle类,这意味着服务接口类必须定在在class path,典型地,作为宿主的一部分。然后,宿主必须通过系统bundle输出服务接口包,安装的bundle才能导入它。这是通过使用org.osgi.framework.system.packages.extra配置属性实现的。参考下面简单的属性查找服务:public interface Lookup public Object lookup(String name);这个包是宿主的一部分,可能jar文件在“java -jar”命令中包含了此包。下面的宿主bundle activator,将使用register/unregister注册反注册属性查找服务。package host.core;import java.util.Map;import org.osgi.framework.BundleActivator;import org.osgi.framework.BundleContext;import org.osgi.framework.ServiceRegistration;import host.service.lookup;public class HostActivator implements BundleActivator private Map m_lookupMap = null; private BundleContext m_context = null; private ServiceRegistration m_registration = null; public HostActivator(Map lookupMap) / Save a reference to the services backing store. m_lookupMap = lookupMap; public void start(BundleContext context) / Save a reference to the bundle context. m_context = context; / Create a property lookup service implementation. Lookup lookup = new Lookup() public Object lookup(String name) return m_lookupMap.get(name); ; / Register the property lookup service and save / the service registration. m_registration = m_context.registerService( Lookup.class.getName(), lookup, null); public void stop(BundleContext context) / Unregister the property lookup service. m_registration.unregister(); m_context = null; 下列代码片段演示了宿主如何建立嵌入式Felix并提供属性查找服务:package host.core;import java.util.List;import java.util.ArrayList;import java.util.Map;import java.util.HashMap;import host.service.lookup.Lookup;import org.apache.felix.framework.Felix;import org.apache.felix.framework.util.FelixConstants;import org.osgi.framework.Constants;public class HostApplication private HostActivator m_activator = null; private Felix m_felix = null; private Map m_lookupMap = new HashMap(); public HostApplication() / Initialize the map for the property lookup service. m_lookupMap.put(name1, value1); m_lookupMap.put(name2, value2); m_lookupMap.put(name3, value3); m_lookupMap.put(name4, value4); / Create a configuration property map. Map configMap = new HashMap(); / Export the host provided service interface package. configMap.put(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA, host.service.lookup; version=1.0.0); / Create host activator; m_activator = new HostActivator(m_lookupMap); List list = new ArrayList(); list.add(m_activator); configMap.put(FelixConstants.SYSTEMBUNDLE_ACTIVATORS_PROP, list); try / Now create an instance of the framework with / our configuration properties. m_felix = new Felix(configMap); / Now start Felix instance. m_felix.start(); catch (Exception ex) System.err.println(Could not create framework: + ex); ex.printStackTrace(); public void shutdownApplication() / Shut down the felix framework when stopping the / host application. m_felix.stop(); m_felix.waitForStop(0); 也可能宿主简单获取bundle context并直接注册服务。使用Bundle服务使用bundle提供的服务与使用宿主bundle activatro是同样的目的。宿主使用bundle的服务,实际上是宿主与bundle必须使用同样的服务类定义。而宿主不能从bundle导入类,这意味着服务接口类必须能在class path访问,典型的是作为宿主的一部分。宿主然后必须通过系统bundle输出服务接口包,bundle才能导入。这是通过使用org.osgi.framework.system.packages.extra配置属性实现的。下面是一个bundle提供简单的命令服务接口实现,可能被使用建立交互shell:package mand;public class Command public String getName(); public String getDescription(); public boolean execute(String commandline);包简单的是宿主的一部分,可能放在“java -jar”命令中JAR文件中。下面是一个bundle activator,简单的提供系统bundle context的访问:package host.core;import org.osgi.framework.BundleActivator;import org.osgi.framework.BundleContext;public class HostActivator implements BundleActivator private BundleContext m_context = null; public void start(BundleContext context) m_context = context; public void stop(BundleContext context) m_context = null; public BundleContext getContext() return m_context; 通过bundle activator,宿主能使用命令服务。下列代码片段描述的一种方式:package host.core;import java.util.List;import java.util.ArrayList;import java.util.Map;import mand.Command;import org.apache.felix.framework.Felix;import org.apache.felix.framework.util.FelixConstants;import org.apache.felix.framework.cache.BundleCache;import org.osgi.framework.Constants;import org.osgi.ut
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 多功能行业管理工具操作手册
- 汽车后市场智能维修与保养服务平台建设
- 企业销售渠道管理分析模板拓宽销售渠道
- 日记采摘乐800字12篇
- 2025年机关车队安全员招聘面试模拟题及答案
- 青海省重点中学2026届高二化学第一学期期中学业质量监测试题含解析
- 商业用生物农药采购协议
- 专业培训服务协议合同书
- 2025年机关车队维修工招聘笔试预测试题及答案
- 小区农户家庭农场合作协议
- GB/T 43137-2023土方机械液压破碎锤术语和商业规格
- 京东集团员工手册-京东
- 2023年苏州市星海实验中学小升初分班考试数学模拟试卷及答案解析
- GB/T 37915-2019社区商业设施设置与功能要求
- GB/T 31298-2014TC4钛合金厚板
- GB/T 27746-2011低压电器用金属氧化物压敏电阻器(MOV)技术规范
- GB/T 22237-2008表面活性剂表面张力的测定
- GB/T 13667.3-2003手动密集书架技术条件
- 导轨及线槽项目投资方案报告模板
- 复旦大学<比较财政学>课程教学大纲
- 书法的章法布局(完整版)
评论
0/150
提交评论