OSGi实战实例以及部署

转自:http://www.cnblogs.com/phoebus0501/archive/2011/03/02/1969361.html

 

对osgi有了一个初步的了解之后,准备写段代码跑跑,一试身手,
先下载了一份Bluedavy 的《OSGI实战》
里边有可以直接运行的代码,双击run.bat运行正常,暗爽!
开始练习《OSGI实战》中用户登录验证模块,一行一行敲代码,第一个变化就是工程之间相互引用不能在Build path里添加工程引用了,改成了在MANIFEST.MF当中添加Import-Package
在学习过程当中还是遇到了不少问题,记录下来,帮助遇到和我同样样问题的少走弯路。
我用的是eclipse3.4 jdk1.6 

1.Import-Package时org.eclipse.equinox.servlet.api这个包死活找不到。
在eclipse3.4已经不存在了直接导入javax.servlet_2.4.0.v200806031604.jar就可以了
如果没有添加javax.servlet会出现  INSTALLED   UserValidatorWebBundle_1.0.0
强行启动会抛出以下异常
org.osgi.framework.BundleException: The bundle could not be resolved. Reason: Missing Constraint: Require-Bundle: javax.servlet; bundle-version="2.4.0"

2.如果使用了Equinox OSGI Declarative Service需要下载 eclipse-equinox-SDK-3.4.2.zip 
因为Declarative Service实现并没有包含在Eclipse的默认软件包中,需要单独从 Eclipse 的的网站上获得,下载包当中的plugins和features复制到eclipse当中重启
org.eclipse.equinox.ds_1.0.0.v20080427-0830.jar是运行时用到的bundle
org.eclipse.equinox.ds用到了org.eclipse.equinox.util_1.0.0.v20080414.jar
都要在config.ini当中添加并启动

3.一切看似启动正常了,log当中还是有以下异常
java.lang.IllegalStateException: Unable to acquire application service. Ensure that the org.eclipse.core.runtime bundle is resolved and started (see config.ini).
还得启动 org.eclipse.osgi.util_3.1.300.v20080303.jar 这个bundle

4.如果http://localhost/demo/page/login.htm 这个页面不能访问可能org.eclipse.equinox.http_1.0.200.v20080421-2006.jar没有启动,如何htm能访问了http://localhost/demo/login 不能访问 可能org.eclipse.equinox.http.servlet_1.0.100.v20080427-0830.jar没有启动

总结一下用户登录验证模块要启动的bundle
id State       Bundle
0 ACTIVE      org.eclipse.osgi_3.4.2.R34x_v20080826-1230
1 ACTIVE      ConfigFileValidatorBundle_1.0.0
2 ACTIVE      DBValidatorBundle_1.0.0
4 ACTIVE      UserValidatorBundle_1.0.0
5 ACTIVE      LDAPValidatorBundle_1.0.0
9 ACTIVE      UserValidatorWebBundle_1.0.0
10 ACTIVE      org.eclipse.equinox.util_1.0.0.v20080414
11 ACTIVE      org.eclipse.equinox.ds_1.0.0.v20080427-0830
12 ACTIVE      javax.servlet_2.4.0.v200806031604
13 ACTIVE      org.eclipse.osgi.services_3.1.200.v20071203
14 ACTIVE      org.eclipse.equinox.http.servlet_1.0.100.v20080427-0830
15 ACTIVE      org.eclipse.equinox.http_1.0.200.v20080421-2006
17 ACTIVE      org.eclipse.osgi.util_3.1.300.v20080303

当缺少什么bundle时,自己去网上下就行,然后用导入Plug- ins and Fragments的方式将bundle导入,便可以引用了,所以别当成什么高深的东西,别忘了在运行时用"Add Required Bundles",它帮我们加入会用的的bundles,这个就帮我们很大的忙了.

在第一个例子(源码中的classic)中,用代码注册的方式来注册服务,即在每个实现服务接口的bundle里的Activator注册自己的服务到指定服务名下,如

  1. package org.riawork.demo.user.validator;  
  2. /* 
  3.  * RIAWork.org 
  4.  *  
  5.  * OSGI Opendoc Demo 
  6.  */  
  7. import org.osgi.framework.BundleActivator;  
  8. import org.osgi.framework.BundleContext;  
  9. import org.osgi.framework.ServiceRegistration;  
  10. import org.riawork.demo.service.user.Validator;  
  11. import org.riawork.demo.service.user.impl.ConfigFileValidatorImpl;  
  12. /** 
  13.  * desc: ConfigFileBundle Activator,采用传统的方式完成服务的注册 
  14.  * 
  15.  * @author jerry 
  16.  */  
  17. public class Activator implements BundleActivator {  
  18.   
  19.     // --------------------------------------------Instance Variables  
  20.       
  21.     private ServiceRegistration serviceReg=null;  
  22.       
  23.     // --------------------------------------------Public Method  
  24.       
  25.     /* (non-Javadoc) 
  26.      * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) 
  27.      */  
  28.     //实现Validator的Bunble都会在Activator里将自己的新的实现注册到Validator.class.getName()名下,这样Validator.class.getName()为名的服务就有多个了  
  29.     public void start(BundleContext context) throws Exception {  
  30.         serviceReg=context.registerService(Validator.class.getName(), new ConfigFileValidatorImpl(), null);  
  31.     }  
  32.   
  33.     /* (non-Javadoc) 
  34.      * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) 
  35.      */  
  36.     public void stop(BundleContext context) throws Exception {  
  37.         if(serviceReg!=null)  
  38.             serviceReg.unregister();  
  39.     }  
  40.   
  41. }  
package org.riawork.demo.user.validator;
/*
 * RIAWork.org
 * 
 * OSGI Opendoc Demo
 */
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
import org.riawork.demo.service.user.Validator;
import org.riawork.demo.service.user.impl.ConfigFileValidatorImpl;
/**
 * desc: ConfigFileBundle Activator,采用传统的方式完成服务的注册
 *
 * @author jerry
 */
public class Activator implements BundleActivator {

	// --------------------------------------------Instance Variables
	
	private ServiceRegistration serviceReg=null;
	
	// --------------------------------------------Public Method
	
	/* (non-Javadoc)
	 * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
	 */
	//实现Validator的Bunble都会在Activator里将自己的新的实现注册到Validator.class.getName()名下,这样Validator.class.getName()为名的服务就有多个了
	public void start(BundleContext context) throws Exception {
		serviceReg=context.registerService(Validator.class.getName(), new ConfigFileValidatorImpl(), null);
	}

	/* (non-Javadoc)
	 * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
	 */
	public void stop(BundleContext context) throws Exception {
		if(serviceReg!=null)
			serviceReg.unregister();
	}

}

在第二个例子(源码中的ds),采用的是在配置文件里声明的方式来发布一个bundle里的服务的,即在 ConfigFileValidatorBundle,DBValidatorBundle,LDAPValidatorBundle这三个实现 UserValidatorBundle接口的bundle里没有Activator来注册它们的实现服务,而是在MANIFEST.MF配置文件里加入 Service-Component: OSGI-INF/component.xml来发布声明在项目目录下的OSGI-INF/component.xml配置文件的服务。

    打包时,按着文档来做是不行的,打包的时候,org.eclipse.osgi的jar包和run.bat是在一个目录里,而在它们目录下再建 configuration目录(存放config.ini文件)和bundles目录(存放自己打包出来的bundle和它们运行依赖的 bundle),还有一点在注意的是拷贝文档里的config.ini内容到config.ini文件是不能运行的,可以是有中文字符在里面。

我这里能运行的如下:

  1. osgi.noShutdown=true  
  2. # 当前系统下运行的 Bundle,可以在此指定 Bundle 的启动顺序,在后续的  
  3. # StartLevel Service章节中会详细的介绍  
  4. #避免Unable to acquire application service. Ensure that the org.eclipse.core.runtime错误  
  5. eclipse.ignoreApp=true  
  6.   
  7. #osgi.bundles=reference\:file\:bundles/ConfigFileValidatorBundle_1.0.0.jar@start,reference\:file\:bundles/DBValidatorBundle_1.0.0.jar@start,reference\:file\:bundles/LDAPValidatorBundle_1.0.0.jar@start,reference\:file\:bundles/org.eclipse.equinox.http_1.0.301.R35x_v20090728.jar@start,reference\:file\:bundles/javax.servlet_2.5.0.v200806031605.jar@start,reference\:file\:bundles/org.eclipse.osgi.services_3.2.0.v20090520-1800.jar@start,reference\:file\:bundles/UserValidatorBundle_1.0.0.jar@start, reference\:file\:bundles/UserValidatorWebBundle_1.0.0.jar@start  
  8. osgi.bundles=plugins/ConfigFileValidatorBundle_1.0.0.jar@start,\  
  9.           plugins/DBValidatorBundle_1.0.0.jar@start,\  
  10.         plugins/LDAPValidatorBundle_1.0.0.jar@start,\  
  11.         plugins/org.eclipse.equinox.http_1.0.301.R35x_v20090728.jar@start,\  
  12.         plugins/javax.servlet_2.5.0.v200806031605.jar@start,\  
  13.         plugins/org.eclipse.osgi.services_3.2.0.v20090520-1800.jar@start,\  
  14.         plugins/UserValidatorBundle_1.0.0.jar@start,\  
  15.         plugins/UserValidatorWebBundle_1.0.0.jar@start,\  
  16.         plugins/org.eclipse.equinox.ds_1.1.1.R35x_v20090806.jar@start,\  
  17.         plugins/org.eclipse.equinox.util_1.0.100.v20090520-1800.jar@start  
  18.   
  19.   
  20. osgi.bundles.defaultStartLevel=4  
osgi.noShutdown=true
# 当前系统下运行的 Bundle,可以在此指定 Bundle 的启动顺序,在后续的
# StartLevel Service章节中会详细的介绍
#避免Unable to acquire application service. Ensure that the org.eclipse.core.runtime错误
eclipse.ignoreApp=true

#osgi.bundles=reference\:file\:bundles/ConfigFileValidatorBundle_1.0.0.jar@start,reference\:file\:bundles/DBValidatorBundle_1.0.0.jar@start,reference\:file\:bundles/LDAPValidatorBundle_1.0.0.jar@start,reference\:file\:bundles/org.eclipse.equinox.http_1.0.301.R35x_v20090728.jar@start,reference\:file\:bundles/javax.servlet_2.5.0.v200806031605.jar@start,reference\:file\:bundles/org.eclipse.osgi.services_3.2.0.v20090520-1800.jar@start,reference\:file\:bundles/UserValidatorBundle_1.0.0.jar@start, reference\:file\:bundles/UserValidatorWebBundle_1.0.0.jar@start
osgi.bundles=plugins/ConfigFileValidatorBundle_1.0.0.jar@start,\
	      plugins/DBValidatorBundle_1.0.0.jar@start,\
		plugins/LDAPValidatorBundle_1.0.0.jar@start,\
		plugins/org.eclipse.equinox.http_1.0.301.R35x_v20090728.jar@start,\
		plugins/javax.servlet_2.5.0.v200806031605.jar@start,\
		plugins/org.eclipse.osgi.services_3.2.0.v20090520-1800.jar@start,\
		plugins/UserValidatorBundle_1.0.0.jar@start,\
		plugins/UserValidatorWebBundle_1.0.0.jar@start,\
		plugins/org.eclipse.equinox.ds_1.1.1.R35x_v20090806.jar@start,\
		plugins/org.eclipse.equinox.util_1.0.100.v20090520-1800.jar@start


osgi.bundles.defaultStartLevel=4

这里不要忘记加入ds的bundle不然用Service-Component: OSGI-INF/component.xml配置就不起作用了,发布不了服务的,因为是由ds的bundle来扫描发现相应的服务,并加于管理的。

 

 

---------------------------------------------------------------------------------------------------------

[转载声明] 转载时必须标注:本文来源于铁木箱子的博客http://www.mzone.cc
[本文地址] 本文永久地址是: http://www.mzone.cc/article/75.html

      在之前的文章中介绍了部署和应用OSGI系统,但是文章中介绍的是手动部署和管理方式。今天介绍的主要就是自动查找Bundle和安装部署的应用,还是以Equinox为实现框架来介绍,同时也参考了Eclipse官方的http://www.eclipse.org/equinox/documents/quickstart.php介绍,有兴趣的朋友可以自行参阅该文档。 首先介绍的是如何让Equinox自动发现新Bundle并部署。首先新建立一个目录demo,在该目录下建立如下文件结构:

  1. demo(目录)
  2. |--configuration(目录)
  3. |--config. ini(文件)
  4. |--plugins(目录)
  5. |--org. eclipse. osgi_3.4.0. v20080605 -1900. jar(文件)
  6. |--org. eclipse. equinox. common_3.4.0. v20080421 -2006. jar(文件)
  7. |--org. eclipse. update. configurator_3.2.200. v20080417. jar(文件)
  8. |--startup. bat(文件)

然后在config.ini中加入如下内容:

  1. osgi. bundles =org. eclipse. equinox. common@ 2 :start,org. eclipse. update. configurator@ 3 :start
  2. eclipse. ignoreApp = true
  3. osgi. noShutdown = true

在startup.bat中加入如下内容:

  1. java -jar org.eclipse.osgi_3.4.0.v20080605-1900.jar -console pause

      这里主要是用到了common和configurator(主要是这个)两个Bundle来自动发现和部署plugins目录下的Bundle,所以,如果有新的Bundle需要发布,只需要放到plugins目录下,然后重新启动OSGI即可。我们在config.ini文件中设置了common的启动级别为2,configurator的启动级别为3,这样,OSGI框架启动后它们将被最先启动,因为Equinox的默认启动级别为4,所以plugins目录下的所有Bundle的启动级别为4。

 

      完成上面的部署后,双击运行startup.bat文件,即可看到OSGI的命令提示符,然后我们输入ss查看所有Bundle的状态,如果plugins目录下有Bundle的话,可以看到这些Bundle的状态为RESOLVED,即表示这些Bundle已经被安装并且解析成功了,等待运行或已停止。我们可以输入sl bundleId 来查看各个Bundle的启动级别。
当然,你也可以使用eclipse提供的本地运行方式来进行上面的操作:-)

你可能感兴趣的:(osgi)