osgi學習資料及問題解決辦法

 

對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註冊自己的服務到指定服務名下,如

Java代碼
  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文件是不能運行的,可以是有中文字符在裏面。

我這裏能運行的如下:

Xml代碼
  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來掃描發現相應的服務,並加於管理的。

發佈了28 篇原創文章 · 獲贊 5 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章