예제2b: 다른 버젼의 사전 서비스 번들

이번예제에서는 예제 2에서 정의했던 사전 서비스의 또 다른 버젼을 만들어 본다. 소스 코드는 동일하지만 다른 점은 영어 사전이 아니라 불어 사전이라는 점이다. 또 하나 다른 점은 사전 서비스 인터페이스를 예제 2에서 정의 하였기 때문에 다시 정의할 필요가 없다는 점이다. 이번 예제의 주제는 하나의 인터페이스에 복수개의 구현이 존재할 수 있다는 점을 보여 주는 것이다. 여기서 만든 예제는 예제 5에서도 사용된다.

아래의 소스 코드는 번들 컨택스트를 사용해서 사전 서비스를 등록한다. 사전 서비스는 activator 클래스의 inner 클래스로 구현한다. 물론 독립된 소스파일로 작성해도 된다. 아래와 같이 Activator.java 파일에 번들을 정의한다.

/*
 * OSGi and Gravity Service Binder tutorial.
 * Copyright (c) 2003  Richard S. Hall
 * http://oscar-osgi.sourceforge.net
**/

package tutorial.example2b;

import java.util.Properties;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceEvent;

import tutorial.example2.service.DictionaryService;

/**
 * 이 클래스는 번들 컨택스트를 사용해서
 * 불어 사전 서비스를 OSGi 프레임워크에 등록하는 번들을
 * 구현한다. 사전 서비스의 인터페이스는 별도 파일에 정의 되어
 * 있고 구현은 이 클래스의 inner 클래스로 정의되어 있다.
 * 클래스는 예제 2와 동일하지만 불어 단어를 격납하고 있다는 점이 다르다.
**/
public class Activator implements BundleActivator
{
    /**
     * BuncleActivator.start() 메서드를 구현한다.
     * 번들 컨택스트를 이용해서 사전 서비스의 인스턴스를 등록한다.
     * 프로퍼티를 서비스에 첨부해서 서비스를 검색할 때 질의될 수 있도록 한다.
     * @param context 프레임워크의 번들용 컨택스트.
    **/
    public void start(BundleContext context)
    {
        Properties props = new Properties();
        props.put("Language", "French");
        context.registerService(
            DictionaryService.class.getName(), new DictionaryImpl(), props);
    }

    /**
     * BundleActivator.stop() 메서드를 구현한다. 프레임워크가
     * 자동으로 등록된 서비스를 제거해 주기 때문에 구현내용은 비워 둔다.
     * @param context 프레임워크의 번들용 컨택스트.
    **/
    public void stop(BundleContext context)
    {
        // NOTE: 자동으로 서비스가 제거된다.
    }

    /**
     * 사전 서비스를 구현하는 private inner 클래스
     * 서비스에 대한 자세한 내용은 DictionaryService를 참고한다.
    **/
    private static class DictionaryImpl implements DictionaryService
    {
        // 사전에 등록되어 있는 단어들의 집합.
        String[] m_dictionary =
            { "bienvenue", "au", "tutoriel", "osgi" };

        /**
         * DictionaryService.checkWord() 메서드를 구현한다.
         * 전달된 단어가 사전에 존재하는지 검사한다.
         * @param word 검사한 단어.
         * @return true 사전에 단어가 존재하는 경우.
         *         false 그외.
        **/
        public boolean checkWord(String word)
        {
            word = word.toLowerCase();

            // 이 코드는 비효율적이다.
            for (int i = 0; i < m_dictionary.length; i++)
            {
                if (m_dictionary[i].equals(word))
                {
                    return true;
                }
            }
            return false;
        }
    }
}

번들의 메타데이터를 저장하는 manifest.mf 파일을 아래와 같이 작성한다. 

Bundle-Activator: tutorial.example2b.Activator
Import-Package: tutorial.example2.service
Bundle-Name: French dictionary
Bundle-Description: A bundle that registers a French dictionary service
Bundle-Vendor: Richard Hall
Bundle-Version: 1.0.0

Bundle-Activator 속성에 BundleActivator를 구현하는 클래스를 기술하고, 이 번들이 필요로 하는 공유 패키지를 Import-Package 속성에 기술한다. 이 import 속성은 예제 2에서 만든 번들에 의해서 충족되게 된다. 왜냐하면 예제2가 이 번들이 import하는 패키지를 export 해주기 때문이다. import 패키지에 대한 상세한 조작은 OSGi 프레임워크가 자동으로 해주게 된다.

컴파일 하려면 osgi.jar 파일이 클래스패스 내에 존재해야 한다. (Oscar의 lib 디렉토리에 들어 있다) 또한 example2.jar 파일도 클래스패스에 들어 있어야 한다. 컴파일은 아래와 같은 명령으로 실행한다.

javac -d c:\classes *.java

실행하면 모든 소스 파일을 컴파일해서 그 결과를 c:\classes 디렉토리의 서브디렉토리에 생성한다. 서브디렉토리명은 소소코드에 정의한 패키지명이 되므로 여기서는 tutorial\example2b가 된다. 위의 명령이 실패하지 않으려면 c:\classes 디렉토리가 존재해야 한다. 컴파일이 끝나면 생성된 패키지 디렉토리를 JAR로 묶어야 한다. 이때 번들의 메타데이터가 들어 있는 manifest 파일도 JAR파일에 같이 묶어야 한다. JAR 파일을 생성하기 위해 아래와 같이 실행한다.

jar cfm example2b.jar manifest.mf -C c:\classes tutorial\example2b


실행하면 manifest 파일을 사용하는 c:\classes 디렉토리의 tutorial\example2b 디렉토리에 있는 자바 클래스 파일들로 JAR 파일을 생성한다. JAR 파일이 생성되었다면 이제 번들을 install하고 start할 준비가 되었다. 

Oscar의 사용법은 usage.html를 참고한다. Oscar를 실행하면 프로파일명을 물어 본다. 우리는 모든 번들을 tutorial이라는 프로파일에 넣을 것이다. Oscar를 실행한 후, 예제1의 번들이 동작중이지 확인해야 한다. ps 라는 Oscar 쉘 명령을 사용해서 모든 번들의 일람과 상태와 식별번호를 확인할 수 있다. 예제1의 번들이 활성화 되어 있지 않다면 start 명령에 ps로 확인한 해당 번들의 식별번호를 사용해서 start 시킨다. c:\tutorial 이라는 디렉토리에 번들을 생성했다고 하면, Oscar의 쉘에서 아래와 같은 명령을 사용해서 install과 start를 실행할 수 있다.

start file:c:/tutorial/example2b.jar

위의 명령은 install과 start를 모두 한번에 실행한다. install과 start를 각각 분리해서 Oscar 쉘에 명령을 내릴 수도 있다. 번들을 stop하려면 stop 이라는 Oscar 쉘 명령어를 사용한다. 예제1의 번들이 start되어 있다면 새 번들이 사전 서비스를 등록할 때 발생한 이벤트를 출력할 것이다. Oscar의 ps 쉘 명령어로 사전 서비스 번들의 식별번호를 확인해서 그 번호를 start와 stop명령의 인수로 전달하면 그 서비스 번들을 start하거나 stop할 수 있다. 사전 서비스 번들을 start하거나 stop시키면 그 때 발생한 이벤트의 내용을 예제1의 번들이 출력해 줄 것이다. 예제 3에서는 사전 서비스를 사용하는 클라이언트를 만들어 볼 것이다. Oscar에서 나갈려면 shutdown 명령을 사용한다.

원문:http://oscar-osgi.sourceforge.net/tutorial/ex2b.html
번역: 허 련호(airless at funit.net)
2009/05

Comments