예제 1: OSGi 서비스를 listen하는 간단한 예제

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

이 예제는 OSGi 서비스를 listen하는 간단한 예제를 만들어 본다. 이 예제가 하는 일은 서비스를 register하고 unregister하는 내용을 출력하는 아주 간단한 예이다. 다음 예제에서 실제로 무언가 처리를 하는 service를 구현한 번들을 만들어 볼 것이다. 번들의 생성에 대한 기본을 이해하기 위해 일단 이 예제를 살펴보자.

 번들이 OSGi 프레임워크에 접근할 때는 BundleContext라는 Unique한 인스턴스를 통해서 이루어 진다. 번들이 이 컨텍스트에 접근하기 위해서는  반드시 BundleActivator 인터페이스를 구현해야 한다. BundleActivator에는 start()와 stop() 메서드가 정의되어 있다. 각각 번들이 시작될 시점과 종료될 시점에 호출되어 지고 매개변수는 번들 컨텍스트이다. 아래의 번들은 BundleActivator 인터페이스를 구현하고 있고, 서비스 이벤트를 listen하라고 컨택스트를 이용해서 자신을 등록한다.

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

package tutorial.example1;

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

/**
 * 이 클래스는 서비스 이벤트를 listen하기 위해 OSGi 프레임워크의 이벤트 메커니즘을
 *  사용하는 간단한 번들을 구현한다. 서비스 이벤트를 받으면 그 이벤트의 내용을 출력한다.
**/
public class Activator implements BundleActivator, ServiceListener
{
    /**
     * BundleActivator.start()를 구현한다. 메세지를 출력한 후
     * 자신을 번들 컨택스트에 서비스 listener로 등록한다.
     * @param context 번들의 프레임워크 컨택스트.
    **/
    public void start(BundleContext context)
    {
        System.out.println("Starting to listen for service events.");
        context.addServiceListener(this);
    }

    /**
     * BundleActivator.stop()을 구현한다. 메세지를 출력한 후
     * 번들 컨택스트로 부터 자신을 제거한다. 
     * @param context 번들의 프레임워크 컨택스트.
    **/
    public void stop(BundleContext context)
    {
        context.removeServiceListener(this);
        System.out.println("Stopped listening for service events.");

        // 노트: 프레임워크가 자동으로 제거해 주기 때문에
        // lister를 명시적으로 제거하는 것은 필수는 아니다.
    }

    /**
     * ServiceListener.serviceChanged()를 구현한다.
     * 프레임워크로 부터 오는 모든 서비스 이벤트의 내용을 출력한다.
     * @param event 발생한 서비스 이벤트
    **/
    public void serviceChanged(ServiceEvent event)
    {
        String[] objectClass = (String[])
            event.getServiceReference().getProperty("objectClass");

        if (event.getType() == ServiceEvent.REGISTERED)
        {
            System.out.println(
                "Ex1: Service of type " + objectClass[0] + " registered.");
        }
        else if (event.getType() == ServiceEvent.UNREGISTERING)
        {
            System.out.println(
                "Ex1: Service of type " + objectClass[0] + " unregistered.");
        }
        else if (event.getType() == ServiceEvent.MODIFIED)
        {
            System.out.println(
                "Ex1: Service of type " + objectClass[0] + " modified.");
        }
    }
}

번들의 소스 코드를 작성했다면, 이제 manifest 파일을 정의해야 한다. 이 파일은 OSGi 프레임워크가 버들을 조작하기 위한 메타데이터가 쓰여져 있다. manifest 파일은 클래스 파일들과 같이 번들의 JAR 파일에 패키지해야 한다. 실재로 이 JAR 파일이 바로 번들이다. 아래와 같은 내용으로 manifest.mf 파일을 작성한다.

Bundle-Activator: tutorial.example1.Activator
Bundle-Name: Service listener example
Bundle-Description: A bundle that displays messages at startup and when service events occur
Bundle-Vendor: Richard Hall
Bundle-Version: 1.0.0

위에서 하나를 제외한 대부분의 내용은 인간이 읽어서 의미를 가지는 것들 뿐이다. 즉, OSGi 프레임워크에 영향을 끼치지 않는다. 제일 첫번째에 나와 있는 메타데이터, Bundle-Activator만이 프레임워크가 사용하는 내용이다. 이 속성은 BundleActivator 인터페이스를 구현하고 있는 클래스가 무엇인지를 프레임워크에 알리는 역할을 한다. OSGi 프레임워크가 번들을 start시킬 때 이 정보를 참조해서 기술한 클래스가 생성되고 start() 메서드를 호출하게 된다. 생성된 인스턴스는 stop() 메서드도 구현하고 있어서 프레임워크가 번들을 stop할 때  stop()메서드가 호출된다.

이제 소스를 컴파일해 보자. 컴파일하려면 클래스패스에 osgi.jar 파일이 필요하다(Oscar의 lib디렉토리에서 다운로드 받을 수 있다). 아래와 같은 명령으로 컴파일 한다.

javac -d c:\classses *.java

실행하면 모든 소스파일을 컴파일해서 c:\classes 디렉토리내에 서브디렉토리에 클래스 파일을 생성한다. 이 예제의 패키지명이 tutorial\example1내에 클래스 파일들이 생성되었을 것이다. 위 명령을 실행하기 전에 c:\classes 디렉토리가 존재해야 한다. 컴파일이 끝났다면 생성된 클래스 패키지 디렉토리를 묶어서 JAR 파일을 생성하자. JAR 파일을 만들 때 번들의 메타데이터인 manifest 파일도 같이 포함시켜야 한다. JAR 파일을 생성하려면 아래와 같이 실행한다.

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

이 명령은 manifest.mf 파일을 참조해서 tutorial\example1 디렉토리에 있는 모든 클래스 파일을 포함하는 JAR파일을 생성한다. JAR 파일이 생성되었다면 번들을 인스톨하고 start할 준비가 된 것이다.

Oscar를 실행하려면 usage.html를 참고한다. Oscar를 실행하면 profile명을 물어 본다. 프로파일명으로 tutorial을 입력한다. 이제 번들을 인스톨하고 start할 차례이다. c:\tutorial이라는 디렉토리에 번들을 생성했다고 하면, Oscar의 쉘 명령라인에 아래와 같은 명령으로 인스톨하고 start할 수 있다.

start file:/c:/tutorial/example1.jar

위의 명령을 실행하면 번들을 단번에 인스톨과 start를 하게 된다. 물론 install 과 start 명령으로 두 단계로 실행해도 동일하다. 번들을 stop하기 위해서는 Oscar 쉘의 stop 명령을 사용한다. 이 예제는 별다를 처리를 하지 않는다는 점을 잊지 말자. 그냥 서비스 이벤트를 listen할 뿐이고 아직 서비스는 등록하지 않는 상태이다. 다음 예제에서 이 번들이 수신할 이벤트를 생성하게 되는 서비스를 등록해 볼 것이다. Oscar를 종료하려면 shutdown 명령을 실행하면 된다.



Comments