• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
    • 軟件測試技術
    • 軟件測試博客
    • 軟件測試視頻
    • 開源軟件測試技術
    • 軟件測試論壇
    • 軟件測試沙龍
    • 軟件測試資料下載
    • 軟件測試雜志
    • 軟件測試人才招聘
      暫時沒有公告

    字號: | 推薦給好友 上一篇 | 下一篇

    利用 Eclipse 開發基于 OSGi 的 Bundle 應用

    發布: 2007-5-24 22:43 | 作者: 楊 曉飛 | 來源: IBM | 查看: 202次 | 進入軟件測試論壇討論

    領測軟件測試網 開放服務網關協議 (Open Services Gateway Initiative),簡稱 OSGi,為網絡服務定義了一個標準的、面向服務的計算環境,為用戶提供了開放的、面向服務組件的、易于部署的編程模型,這個編程模型允許用戶將定義好的接口規范綁定到 OSGi 運行環境中的特定Service,在構件 SOA 面向服務為中心的企業應用的過程中,OSGi 技術正發揮越來越重要的作用。在本文中,將介紹 OSGi 的概念和體系結構,并且利用 Eclipse 3.2 開發一個基于 OSGi 規范的服務應用 Bundle。通過學習本文,讀者可以了解到如何開發和部署基于 OSGi 規范的 Bundle 應用。

    OSGi 規范簡介

    OSGi 聯盟建立于 1999 年,是一個非贏利機構,旨在建立一個開放的服務規范。OSGi 規范為網絡服務定義了一個標準的、面向組件的計算環境,它最初的目的就是為各種嵌入式設備提供通用的軟件運行平臺,屏蔽設備操作系統與硬件區別的中間件平臺,通過這個平臺,可以對不同軟件商提供的應用(OSGi 中稱為 Bundle)進行組件的生命周期管理的能力,如應用組件可以從運行中被安裝、升級或者移除而不需要中斷設備的操作,應用組件可以動態的發現和使用其他庫或者應用程序。由于 OSGi 技術具有服務組件模塊化、動態加載應用等優點,正被越來越多的領域關注,如嵌入設備制造業、汽車制造業、企業應用等。目前,OSGi 聯盟發布的最新的 OSGi 服務規范為 4.0,讀者可以查閱參考資料了解詳細信息。





    回頁首


    OSGi 體系結構

    OSGi 的體系架構是基于插件式的軟件結構,包括一個 OSGi 框架和一系列插件,在 OSGi中,插件稱為 Bundle,其中,OSGi 框架規范是 OSGi 規范的核心部分,它提供了一個通用的、安全可管理的 Java 框架,通過這個框架,可以支持 Bundle 服務應用的部署和擴展。Bundle 之間可以通過 Import Package 和 Require-Bundle 來共享 Java 類,在 OSGi 服務平臺中,用戶通過開發 Bundle 來提供需要的功能,這些 Bundle 可以動態加載和卸載,或者根據需要遠程下載和升級。OSGi 體系結構圖如圖 1 所示:


    圖示1 OSGi 體系結構
    圖示1 OSGi 體系結構

    其中:

    Execution Environment:

    Bundle 應用所倚賴運行的 Java 執行環境,如 J2SE-1.4、CDC-1.0 等都是可用的執行環境。

    Modules:

    模塊層定義了 Bundle 應用的加載策略。OSGi 框架是一個健壯并且嚴格定義的類加載模型。在大多數 Java 應用中,通常只有一個單獨的 ClassPath,它包含了所有的 Java 類文件和資源文件,OSGi基于Java技術,對于每個實現了 BundleActivator 接口的 Bundle 應用,為它生成一個單獨的 ClassLoader,使得 Bundle 應用的組織更加模塊化。

    Life Cycle:

    生命周期層可以動態地對 Bundle 進行安裝、啟動、停止、升級和卸載等操作。該層基于模塊層,提供了一組 API 來控制 Bundle 應用的運行時操作。

    Service Registry 和 Services:

    OSGi 服務層定義了一個集成在生命周期層中的動態協作模型,是一個發布、動態尋找、綁定的服務模型。一個服務通常是一個 Java 對象實現了特定的服務接口,并且通過服務注冊,被綁定到 OSGi 的運行環境中。Bundle 應用可以注冊發布服務,動態綁定服務,并且在服務注冊狀態改變時,可以接受到事件消息等。

    Security:

    OSGi 的安全管理是基于 Java2 安全體系的,貫穿在 OSGi 平臺的所有層中,它能夠對部署在 OSGi 運行環境中的 Bundle 應用進行詳細的管理控制。





    回頁首


    Bundle 生命周期的狀態

    在一個動態擴展的 OSGi 環境中,OSGi 框架管理 Bundle 的安裝和更新,同時也管理 Bundle 和服務之間的依賴關系。一個 Bundle 可能處于以下六個狀態,如圖 2 所示:


    圖示 2 Bundle 狀態圖
    圖示 2 Bundle 狀態圖

    INSTALLED:安裝完成,本地資源成功加載。

    RESOLVED:依賴關系滿足,這個狀態意味該Bundle要么已經準備好運行,要么是被停止了。

    STARTING:Bundle正在被啟動,BundleActivator的start()方法已經被調用但是還沒有返回。

    STOPPING:Bundle正在被停止,BundleActivator的stop()方法已經被調用但是還沒有返回。

    ACTIVE:Bundle 被成功啟動并且在運行。

    UNINSTALLED:bundle被卸載并且無法進入其他狀態。

    Bundle接口定義了getState()方法來返回Bundle的狀態。





    回頁首


    OSGi 標準服務

    在 OSGi 平臺之上,OSGi 聯盟定義了很多服務。服務是由一個 Java Interface 來定義的,Bundle 可以實現這個接口并且把服務注冊到服務注冊表中去,用戶可以從注冊表中找到需要的服務來使用,并且可以響應特定服務的狀態改變,如服務注冊和服務取消。下面簡單介紹一下 OSGi Release 4 的一些主要服務。OSGi 框架提供了權限管理服務,包管理服務和最初加載系統服務。這些服務是 OSGi 框架的一部分并且管理著 OSGi 框架的運作。

    Permission Admin Service:權限管理是指 Bundle 是否許可其他的 Bundle 的代碼。當前的或者其他的 Bundle 的權限可以通過這個服務來操作,一旦被設定權限,馬上就生效。 Package Admin Service:Bundle 之間可以共享包內的 Java 類和資源,bundle 的更新可能需要 OSGi 框架重新解析 Bundle 之間的依賴關系,這個服務提供了 OSGi 服務平臺中包的共享狀態信息。

    Start Level Service:Start Level是指一些在特定Bundle起動之前必須運行或者初始化的一系列 bundle。Start Lever Service 可以設置當前OSGi服務框架初始的Start Level,并且可以指定和查詢特定Bundle的Start Level。





    回頁首


    使用 Eclipse 開發 Bundle 應用

    Equinox 框架是 Eclipse 組織基于 OSGi Release 4 的一個實現框架,它實現了 OSGi 規范的核心框架和許多標準框架服務的實現。關于Equinox項目的詳細信息,請查閱參考資料信息。在本文中,我們使用 Eclipse 3.2 平臺開發兩個基于 OSGi 的 Bundle 應用,其中第一個 Bundle 應用聲明、實現并注冊了一個姓名查詢服務,用于判斷所給姓名是否在已定義的查詢列表中;第二個 Bundle 應用查詢并引用第一個 Bundle 應用所注冊的姓名查詢服務,如果用戶所給的姓名包含在查詢列表中,將返回正確的信息,最后,將開發的 Bundle應用部署的 Equinox OSGi 框架中,用戶可以在 OSGi 控制命令行中輸入命令來查詢關于框架和 Bundle 應用的具體信息。讀者可以從參考資料中獲得本文 Bundle 應用的源代碼。

    (1)創建 Plug-in Project,在 Eclipse 3.2 開發環境中,從菜單欄選擇 File > New > Project... ,打開 New Project 向導,可以看到有Plug-in Project創建向導,創建一個Plug-in 項目。項目名為 example 的 Bundle 應用,該應用實現并注冊了一個姓名查詢服務,實現了 BundleActivator 接口。選擇 Equinox 框架作為 Bundle 應用運行的 OSGi 服務平臺。


    圖示 3 Plug-in 項目向導
    圖示 3 Plug-in 項目向導

    (2)實現OSGi服務通常需要兩個步驟,首先定義所提供服務的接口,然后實現這個服務接口。在本例中,我們創建一個姓名查詢服務用來查詢所給姓名是否有效。首先定義姓名查詢接口NameService.java。下面是該接口的源代碼:


    NameService Interface 源代碼
    package example.service;
                /**
                * A simple service interface that defines a name service.
                * A name service simply verifies the existence of a Name.
                **/
                public interface NameService {
                /**
                * Check for the existence of a Name.
                * @param name the Name to be checked.
                * @return true if the Name is in the list,
                *         false otherwise.
                **/
                public boolean checkName(String name);
                }
                

    該服務接口很簡單,只包含一個需要實現的方法。為了將服務接口和服務實現相分離,方便其他 Bundle 引用該服務,我們通常需要將該服務接口單獨放在一個包內,本例中,存放NameService.java 接口的 Java 包為 example.service。接下來,需要實現 NameService 接口,并且注冊該服務。在本例中,我們用內部類實現了該接口,下面是該 Bundle 應用的部分源代碼。


    Example Bundle部分源代碼
    	public void start(BundleContext context) throws Exception {
                Properties props = new Properties();
                props.put("ClassRoom", "ClassOne");
                context.registerService(NameService.class.getName(), new NameImpl(),
                props);
                }
                private static class NameImpl implements NameService {
                // The set of names contained in the arrays.
                String[] m_name = { "Marry", "John", "David", "Rachel", "Ross" };
                /**
                * Implements NameService.checkName(). Determines if the passed name is
                * contained in the Array.
                *
                * @param name
                *            the name to be checked.
                * @return true if the name is in the Array, false otherwise.
                */
                public boolean checkName(String name) {
                // This is very inefficient
                for (int i = 0; i < m_name.length; i++) {
                if (m_name[i].equals(name)) {
                return true;
                }
                }
                return false;
                }
                }
                

    在start()方法中,利用BundleContext注冊一個姓名查詢服務,并且為該服務設置相關屬性以便服務查詢。在實現姓名查詢服務時,我們簡單定義了一個靜態數組用于存放有效的姓名信息。

    (3)定義Bundle描述文件MANIFEST.MF,Bundle應用example的MANIFEST.MF文件如下:


    MANIFEST.MF文件信息
    Manifest-Version: 1.0
                Bundle-ManifestVersion: 2
                Bundle-Name: Example Bundle
                Bundle-SymbolicName: example
                Bundle-Version: 1.0.0
                Bundle-Activator: example.osgi.Activator
                Bundle-Localization: plugin
                Import-Package: org.osgi.framework;version="1.3.0"
                Export-Package: example.service
                

    其中,Bundle-Activator屬性指明了實現BundleActivator接口的類,該類用來啟動和停止Bundle應用。Export-Package屬性指定了該Bundle輸出的共享包,該屬性可以使其他的Bundle應用引用我們所定義的服務接口。

    (4)創建項目名為exampleClient的Bundle應用,該應用在OSGi平臺上查尋并引用example Bundle應用已經注冊的姓名查詢服務,然后從標準輸入讀入用戶所輸入的姓名信息,判斷所輸入姓名是否有效。exampleClient應用的部分源代碼如下,讀者可從參考資料中獲得完整源代碼。


    ExampleClient Bundle部分源代碼
    	public void start(BundleContext context) throws Exception {
                ServiceReference[] refs = context.getServiceReferences(
                NameService.class.getName(), "(ClassRoom=*)");
                if (refs != null) {
                try {
                System.out.println("Enter a blank line to exit.");
                BufferedReader in = new BufferedReader(new InputStreamReader(
                System.in));
                String name = "";
                // Loop endlessly.
                while (true) {
                // Ask the user to enter a name.
                System.out.print("Enter a Name: ");
                name = in.readLine();
                // If the user entered a blank line, then
                // exit the loop.
                if (name.length() == 0) {
                break;
                }
                // First, get a name service and then check
                // if the name is correct.
                NameService nameservice = (NameService) context
                .getService(refs[0]);
                if (nameservice.checkName(name)) {
                System.out.println("The Name is Correct.");
                } else {
                System.out.println("The Name is Incorrect.");
                }
                // Unget the name service.
                context.ungetService(refs[0]);
                }
                } catch (IOException ex) {
                }
                } else {
                System.out.println("Couldn't find any name service...");
                }
                }
                





    回頁首


    Bundle的部署及運行

    在Eclipse平臺中,選擇File-->Export...菜單,將開發的example和exampleClient兩個Bundle應用導出成Jar文件,以便將它們部署到OSGi服務平臺中。選擇將要運行的Bundle應用,鼠標右鍵點擊,在彈出菜單中,選擇Run AS-->Equinox FrameWork來啟動OSGi服務平臺。在Equinox啟動配置控制臺中,可以為Bundle應用設置默認的Start Level和Bundle應用是否需要自動啟動等選項。在本例中,為了講解如何安裝及啟動Bundle應用,只將example Bundle應用設為自動啟動,而exampleClient Bundle應用需要我們用命令安裝及啟動。

    當OSGi Equinox FrameWork啟動后,在OSGi控制命令臺中輸入ss命令,可以查看OSGi服務平臺中已經安裝的Bundle應用信息及其狀態。如圖4所示,可以看到當前OSGi服務平臺中有兩個Bundle處于Active狀態,其中,system.bundle_3.2.0.v20060328為OSGi框架的系統Bundle,而example_1.0.0為注冊姓名查詢服務的Bundle應用,1.0.0為Bundle應用的版本號。


    圖示4 Bundle信息查詢
    圖示4 Bundle信息查詢

    在OSGi控制命令臺中利用install命令安裝exampleClient Bundle應用,用ss命令查看安裝后的Bundle應用信息及其狀態。如圖5所示:


    圖示5 安裝Bundle
    圖示5 安裝Bundle

    在OSGi控制命令臺中利用start命令安裝exampleClient Bundle應用,用戶可輸入姓名,利用姓名查詢服務來判斷所輸入姓名是否有效,用ss命令查看啟動后的Bundle應用信息及其狀態。如圖6所示:


    圖示6 啟動Bundle
    圖示6 啟動Bundle

    用戶在在OSGi控制命令臺中,可利用stop命令來停止指定的Bundle應用,close命令用來停止并退出OSGi控制命令臺。關于OSGi Equinox FrameWork控制臺命令的詳細信息,可查看參考資料。





    回頁首


    總結

    OSGi服務框架提供了開放的、面向服務的、易于部署的編程模型,在構件面向服務為中心的企業應用的過程中,OSGi 技術正發揮越來越重要的作用。目前,Eclipse 3.2 體系架構是參照OSGi實現的,Equinox框架是 Eclipse 組織基于OSGi Release 4 的一個實現框架,它實現了OSGi 規范的核心框架和許多標準框架服務。在本文中,我們利用Eclipse 平臺開發了兩個Bundle應用,并且在Bundle應用中,聲明、實現、注冊并引用了一個簡單的服務,最后,將Bundle應用部署到Equinox OSGi服務框架中。通過本文,讀者可以了解如何開發和部署基于OSGi規范的Bundle應用。






    回頁首


    下載

    名字大小下載方法
    example.zip 8KB HTTP

    延伸閱讀

    文章來源于領測軟件測試網 http://www.kjueaiud.com/


    關于領測軟件測試網 | 領測軟件測試網合作伙伴 | 廣告服務 | 投稿指南 | 聯系我們 | 網站地圖 | 友情鏈接
    版權所有(C) 2003-2010 TestAge(領測軟件測試網)|領測國際科技(北京)有限公司|軟件測試工程師培訓網 All Rights Reserved
    北京市海淀區中關村南大街9號北京理工科技大廈1402室 京ICP備10010545號-5
    技術支持和業務聯系:info@testage.com.cn 電話:010-51297073

    軟件測試 | 領測國際ISTQBISTQB官網TMMiTMMi認證國際軟件測試工程師認證領測軟件測試網

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>