OSGiフレームワーク Apache Felix その5


前回のOSGiフレームワーク Apache Felix その4 - etc9では、ServiceListener によるサービスの動的な変更について見てきましたが、このための用途として、ServiceTracker というクラスが提供されています。

ServiceTrackerとは

ServiceTracker は、サービスの動的な追従を可能とするクラスです。

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;

public class Activator implements BundleActivator {

    private BundleContext m_context = null;
    private ServiceTracker m_tracker = null;

    public void start(BundleContext context) throws Exception {
        m_context = context;

        m_tracker = new ServiceTracker(
            m_context,
            m_context.createFilter(
                "(&(objectClass=" + DictionaryService.class.getName() + ")" +
                "(Language=*))"), null);
        m_tracker.open();

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

            while (true) {
                System.out.print("Enter word: ");
                word = in.readLine();

                DictionaryService dictionary = (DictionaryService) m_tracker.getService();

                if (word.length() == 0) {
                    break;
                } else if (dictionary == null) {
                    System.out.println("No dictionary available.");
                } else if (dictionary.checkWord(word)) {
                    System.out.println("Correct.");
                } else {
                    System.out.println("Incorrect.");
                }
            }
        } catch (Exception ex) { }
    }

    public void stop(BundleContext context){ }
}

m_tracker.open() にてサービスの動的な追従を開始します。m_tracker.getService()にて追跡しているサービスの中で優先度の高いサービスを取得できます。追従するサービスは、サービストラッカーのコンストラクタで、m_context.createFilterによりフィルタ条件を指定することで行います。

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

バンドルの作成

> cd work\example5
> javac -classpath ..\..\bin\felix.jar;..\example2\example2.jar tutorial\example5\*.java
> jar cfm example5.jar MANIFEST.MF tutorial\example5

動作確認

java -jar ./bin\felix.jar
-> start file:work\example2\example2.jar
-> start file:work\example5\example5.jar
Enter a blank line to exit.
Enter word: osgi
Correct.
Enter word:
-> ps
START LEVEL 1
   ID   State         Level  Name
[   0] [Active     ] [    0] System Bundle (2.0.0)
[   1] [Active     ] [    1] Apache Felix Bundle Repository (1.4.1)
[   2] [Active     ] [    1] Apache Felix Shell Service (1.4.0)
[   3] [Active     ] [    1] Apache Felix Shell TUI (1.4.0)
[   4] [Active     ] [    1] English dictionary (1.0.0)
[   5] [Active     ] [    1] Service Tracker-based dictionary client (1.0.0)

動的な追従については、この例ではよくわかりませんが、正しく動いていることが確認できます。
時間があったらもう少し分かりやすい例で書きます・・