(07) Apache Felix 入門 - 07

1、Service Tracker Dictionary Service

Example4 已經能夠應對服務的動態可用性問題,但是其處理過於複雜,於是 OSGI 規範提出了 Service Tracker 的概念以解決 Example4 中出現的問題,Service Tacker 翻譯過來的意思就是“服務追蹤者”的信息,其作用類似於 Java 中的 TCP 服務器,當服務端開始監聽接口的時候,則當前線程會停止,直至發現有客戶端請求連接該端口爲纔會繼續執行下面的代碼。 而 ServiceTracker 則是監聽符合特定篩選條件的服務,當 ServiceTacker 開啓之後,如果沒有任何符合篩選條件的服務被發現,則會拋出 org.osgi.framework.BundleException,具體使用示例如下:

/*
 * Apache Felix OSGi tutorial.
**/

package tutorial.example5;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.util.tracker.ServiceTracker;

import tutorial.example2.service.DictionaryService;

/**
  * 使用 ServiceTacker 重構 Example4 例子。
**/
public class Activator implements BundleActivator
{
    // Bundle's context.
    private BundleContext m_context = null;
    // The service tacker object.
    private ServiceTracker m_tracker = null;

    /**
     * Implements BundleActivator.start(). Crates a service
     * tracker to monitor dictionary services and starts its "word
     * checking loop". It will not be able to check any words until
     * the service tracker find a dictionary service; any discovered
     * dictionary service will be automatically used by the client.
     * It reads words from standard input and checks for their
     * existence in the discovered dictionary.
     * (NOTE: It is very bad practice to use the calling thread
     * to perform a lengthy process like this; this is only done
     * for the purpose of the tutorial.)
     * @param context the framework context for the bundle.
    **/
    public void start(BundleContext context) throws Exception
    {
        m_context = context;

        // Create a service tracker to monitor dictionary services.
        m_tracker = new ServiceTracker(
            m_context,
            m_context.createFilter(
                "(&(objectClass=" + DictionaryService.class.getName() + ")" +
                "(Language=*))"),
            null);

        System.out.println("wait DictionaryService...");    
        m_tracker.open();

        try
        {
            System.out.println("Enter a blank line to exit.");
            String word = "";
            BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

            // Loop endlessly.
            while (true)
            {
                // Ask the user to enter a word.
                System.out.print("Enter word: ");
                word = in.readLine();

                // Get the selected dictionary service, if available.
                DictionaryService dictionary = (DictionaryService) m_tracker.getService();

                // If the user entered a blank line, then
                // exit the loop.
                if (word.length() == 0)
                {
                    break;
                }
                // If there is no dictionary, then say so.
                else if (dictionary == null)
                {
                    System.out.println("No dictionary available.");
                }
                // Otherwise print whether the word is correct or not.
                else if (dictionary.checkWord(word))
                {
                    System.out.println("Correct.");
                }
                else
                {
                    System.out.println("Incorrect.");
                }
            }
        } catch (Exception ex) { }
    }

    /**
     * Implements BundleActivator.stop(). Does nothing since
     * the framework will automatically unget any used services.
     * @param context the framework context for the bundle.
    **/
    public void stop(BundleContext context)
    {
    }
}

構建 manifest.mf

Bundle-Name: Service Tracker-based dictionary client
Bundle-Description: A dictionary client using the Service Tracker.
Bundle-Vendor: Apache Felix
Bundle-Version: 1.0.0
Bundle-Activator: tutorial.example5.Activator
Import-Package: org.osgi.framework,
 org.osgi.util.tracker,
 tutorial.example2.service

編譯、打包:

D:\devInstall\apache\felix-framework-6.0.0\examples\demo05\src> javac -cp ..\..\demo02\target\example2.jar;..\..\..\bin\felix.jar -encoding UTF-8 -d ../target tutorial\example5\*.java
D:\devInstall\apache\felix-framework-6.0.0\examples\demo05\src> cd ../target
D:\devInstall\apache\felix-framework-6.0.0\examples\demo05\src> cp ../src/manifest.mf ./
D:\devInstall\apache\felix-framework-6.0.0\examples\demo05\src> jar cvfm example4.jar manifest.mf -C . .
已添加清單
正在添加: manifest.mf(輸入 = 311) (輸出 = 183)(壓縮了 41%)
正在添加: tutorial/(輸入 = 0) (輸出 = 0)(存儲了 0%)
正在添加: tutorial/example5/(輸入 = 0) (輸出 = 0)(存儲了 0%)
正在添加: tutorial/example5/Activator.class(輸入 = 2132) (輸出 = 1174)(壓縮了 44%)

安裝、運行:

g! lb                                                                                                           16:58:41
START LEVEL 1
   ID|State      |Level|Name
    0|Active     |    0|System Bundle (6.0.0)|6.0.0
    1|Active     |    1|jansi (1.17.1)|1.17.1
    2|Active     |    1|JLine Bundle (3.7.0)|3.7.0
    3|Active     |    1|Apache Felix Bundle Repository (2.0.10)|2.0.10
    4|Active     |    1|Apache Felix Gogo Command (1.0.2)|1.0.2
    5|Active     |    1|Apache Felix Gogo JLine Shell (1.1.0)|1.1.0
    6|Active     |    1|Apache Felix Gogo Runtime (1.1.0)|1.1.0
    7|Active     |    1|Service listener example (1.0.0)|1.0.0
g! install file:./examples/demo05/target/example5.jar
Bundle ID: 16
g! start 16
org.osgi.framework.BundleException: Unable to resolve [16](R 16.0): missing requirement [[16](R 16.0)] osgi.wiring.package; (osgi.wiring.package=tutorial.example2.service) Unresolved requirements: [[[16](R 16.0)] osgi.wiring.package; (osgi.wiring.package=tutorial.example2.service)]
g! install file:./examples/demo02/target/example2.jar                                                           16:47:46
Bundle ID: 17
g! start 17                                                                                                     16:52:06
Ex1: Service of type tutorial.example2.service.DictionaryService registered.
g! start 16                                                                                                     16:52:10
wait DictionaryService...
Enter a blank line to exit.
Enter word: 

上面再安裝 example5.jar 的之前,首先將前面註冊的 DictionaryService 全部取消註冊,方法是直接全部卸載掉,然後安裝 example5.jar,啓動發現啓動失敗,原因是依賴的服務 DictionaryService 沒有被註冊, 安裝 example2.jar, 註冊了一個 English Service,則啓動 example5.jar 成功。 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章