Equinox 을 이용해서 OSGi 번들을 만들고 실행해보는 방법을 이해하고, Equinix 의 사용현황을 알아본다.
Equinox 개요
Equinix 는 Eclipse 재단에서 만들고 있는 OSGi Core Framework 및 기타 부속물의 구현물이다. Eclipse 재단은 Eclipse 3.0 버전부터 Eclipse 의 내부 프레임워크로 OSGi 를 채택했으며, OSGi 구현을 위한 프로젝트가 Equinix 이다.
현재 Equinix 는 별개의 프로젝트가 아니라 Eclipse RCP 와 IDE 플랫폼 개발 프로젝트로 흡수되었다.
Equinix 는 OSGi 가 (웹애플리케이션으로서의) Server Side 에서 주목받게 됨에 따라 Eclipse 플랫폼으로서가 아니라 Server Side 의 독자적인 플랫폼으로서의 가능성에 주목받고 있다. Equinox 를 Server Side 에서 쓰기 위한 작업도 진행되고 있다.
Eclipse 재단은 EPL (Eclipse Public License) v1.0 라이선스을 사용하는데, 이 라이선스에 의하면 상업적인 목적으로 소스 및 오브젝트 파일들을 쓰는 것은 허용되나 이로 인해 발생되는 모든 책임을 질 것과 EPL v1.0 라이선스 파일을 제품에 포함시킬 것을 요구하고 있다.
Equinox 사용하기
Equinox 는 Eclipse 플랫폼의 기반 Framework 이지만, Eclipse 와 관계없이 Equinox 만을 쓰는 것도 가능하다.
Eclipse 설치본에서 다음 파일을 사용하면 osgi> 로 표기되는 Equinox 런타임의 콘솔을 볼 수 있다.
다음은 org.eclipse.osgi_3.3.0.v20070530.jar 파일을 써서 콘솔을 띄운 모습이다.
Equinox 에서 실행할 Bundle 은 jar 파일 형태를 가지며, jar 파일내에는 org.osgi.framework.BundleActivator 인터페이스를 구현한 Activator 클래스가 포함되어 있어야 하고, MANIFEST.MF 파일에는 Bundle 이 구동되기 위한 정보가 담겨 있어야 한다.
이런 Bundle 을 만드는 데에는 Eclipse 를 이용하면 편리하다. 이에 앞서 Bundle 의 구조를 간단하게 살펴보기 위해 Console 에서 직접 만드는 예를 먼저 살펴본다.
Console 에서 Equinox 용 Bundle 작성 및 실행
Bundle 소스코드 작성과 컴파일하기
Console에서 텍스트 편집기로 직접 작성해서 빌드하고 실행하는 예이다.
먼저, org.eclipse.osgi_3.3.0.v20070530.jar 파일이 있는 디렉토리로 이동한다.
public class MyFirstBundle implements BundleActivator { public void start(BundleContext bc) { System.out.println("생애 첫 번들 시작~ 2번째~"); }
public void stop(BundleContext bc) { System.out.println("생애 첫 번들 끝~ 2번째~"); } }
stop() 메소드가 호출되는 것은 이전 소스코드 내용이고, 다시 한 번 update 1 을 실행하면 수정된 소스코드 내용이 실행된 것을 알 수 있다.
다음 그림은 다시 한 번 update 1 을 실행한 모습이다.
Eclipse 에서 Equinox 용 Bundle 작성 및 실행
Eclipse에서 Bundle 을 작성해서 빌드하고 실행하는 예이다.
Project Wizard 를 이용한 Bundle Project 만들기
Eclipse에는 명시적으로 OGSi Bundle 을 만들 수 있는 Project Wizard 가 없는 것처럼 보인다. 하지만, Eclipse Plug-in 이 사실 OSGi Bundle 이기 때문에 Eclipse Plug-in Project Wizard 를 이용하면 Eclipse 에서 OSGi Bundle 을 만들 수 있다.
다음 그림처럼 Plug-in Project Project Wizard 를 선택해서 예제 Project 를 선택한다.
이제 Project name 을 입력하고, Target Platform 으로 OSGi 를 선택한다. OSGi framework 으로는 standard 와 Equinox 를 선택할 수 있는데, 여기에서는 Equinox 를 선택한다.
그 다음 화면에서 Finish 버튼을 누르지 말고, Next 버튼을 눌러야 예제 소스코드를 선택할 수 있다.
Hello OSGi Bundle 예제를 선택하고 Finish 버튼을 누르면 다음 화면과 같이 예제 Project 를 볼 수 있다.
이 화면에서는 MANIFEST.MF 파일의 내용을 바로 수정하거나 OSGi framework 런타임을 기동/기동시키는 등의 조작이 가능하다.
이제, 왼쪽 Package Explorer 에서 mindwing_bundle.Activator.java 파일을 연다.
이 상태에서 다음 그림과 같이 실행환경을 만든다.
Target Platform 은 다음과 같이 하나만 선택하도록 한다.
이제 Run 버튼을 누르면 다음 그림과 같이 Equinox 의 Console 이 뜨면서 Bundle 이 실행되는 것을 볼 수 있다. (ss 명령으로 현재 실행중인 Bundle 의 상태도 조회하였다.)
Bundle 이 실행된 상태에서 소스코드를 수정하면 Eclipse 에서 알아서 빌드 후 Bundle jar 파일까지 만들어준다. 소스코드를 수정한 다음 Bundle 의 ID 인 1 번으로 update 를 하면 별도로 컴파일을 하고 Bundle jar 파일을 만드는 과정이 없이 바로 결과를 확인할 수 있는 것을 볼 수 있다.
Bundle 간 메소드 호출하기
Bundle 은 package 단위별로 외부에 자신을 노출시킬 수 있다.
노출시킬 package 와 pacage 의 버전등에 관한 정보는 모두 MANIFEST.MF 파일에 기재되어야 하는데, Eclipse 에서는 MANIFEST.MF 파일을 수정하기 위한 다양한 view 를 제공한다.
Package 노출하기
A Bundle 과 B Bundle 이 있을 때, B Bundle 이 노출시킨 package 를 A Bundle 이 사용하는 예이다.
다음과 같이 A 와 B 라는 이름으로 2개의 Bundle 프로젝트를 만든 상태에서 설명을 시작한다.
B Bundle 에는 b_export 패키지가 있는데, MANIFEST.MF 파일에 패키지 이름을 써주면 된다. Eclipse 에서 B Bundle 의 MANIFEST.MF 파일을 더블클릭하면 다양한 view 로 편집할 수 있는 편집기를 볼 수 있다.
다음 그림과 같이 아래에 있는 탭에서 Runtime 을 선택한다.
Export Packages 부분에 있는 Add... 버튼을 눌러서 다음 화면을 띄우고, b_export 패키지를 선택한다.
그러면, 다음과 같이 b_export 가 export 되고 있다는 것을 알 수 있다.
여기에서 Properties... 버튼을 눌러서 다음 그림과 같이 버전을 1.0.0 으로 기입한다. (기입하지 않았을 때의 기본값은 1.0.0 이다. 최대 4자리까지 숫자를 입력할 수 있다.)
이제, 아래 탭에 있는 MANIFEST.MF 를 눌러서 실제 파일에는 어떻게 기재되어 있는지 살펴본다.
이제 이 파일을 저자한 다음에 다음 그림과 같이 export 된 package 를 이용할 A Bundle 의 MANIFEST.MF 를 더블클릭해서 열고, Dependency 탭을 누른 다음 Imported Packages 의 Add... 버튼을 누르고. b_export 을 선택한다.
다음 그림과 같이 MANIFEST.MF 파일에서 수정내용을 확인할 수 있다.
실행결과를 보기전에 관련 소스코드를 살펴보면, B Bundle 의 노출된 패키지에 속한 클래스인 b_export.B_Export 클래스는 다음과 같다.
package b_export;
public class B_Export { public void b_export() { System.out.println(" === B번들의 b_export() 메소드 호출됨."); } }
이 클래스를 사용하기 위한 A Bundle 에서 a.Activator 클래스와 a.A_Import 클래스는 각각 다음과 같으며, 클래스를 바로 사용할 수 있는 것을 알 수 있다.
이제 Equinox 를 기동하면 다음과 같은 화면과 같이, dependency 가 걸려있는 Bundle B 가 먼저 start 되고, 그 다음에 Bundle A 가 start 되고, Bundle A 에서 Bundle B 의 b_export() 메소드가 호출되는 것을 볼 수 있다.
Service 등록과 사용하기
Eclipse에서 Service 를 작성해서 다른 Bundle 에서 이를 이용하는 예이다.
Service 는 어떤 Bundle 이 다른 Bundle 에게 자신을 노출할 수 있는 또 하나의 방법이다. Bundle 의 Package 노출은 Package 이름이나 Class 이름을 원치 않는 상황에서도 노출해야만 하며, 노출된 Class 가 정확히 노출된 목적에만 맞게 만들어진 것이 아닐 수도 있다.
이에 비해 Service 를 이용하면 잘 알려진 Interface 를 이용해서 구현 및 탐색이 이루어지기 때문에, Bundle 상호간 정확한 목적하에 상호작용이 이루어질 수 있으며, Service 구현체는 해당 Interface 의 뒤에 가려져있기 때문에 상황에 따라 런타임에 구현체만 바꾸는 것도 가능하다.
Service 는 일반적인 Java 인스턴스면 모두 Service Registry 에 등록이 가능하며, 명시적으로 BundleContext 에서 unregister 하거나 Service 를 제공한 Bundle 이 stop 되면 자동으로 Service Registry 에서 제거된다.
Service 를 만들고 등록하고 사용하기
앞서 설명한 Bundle 만드는 방식대로 S1 Bundle 을 만들고, 다음 소스코드를 참고해서 인터페이스인 hello.HelloService 클래스와 구현체인 hello.impl.HelloService 클래스를 만든다. 그리고, 이를 Service Registry 에 등록하기 위한 코드도 Activator 클래스에 추가한다.
package hello;
public interface HelloService { public void sayHello(); }
package hello.impl;
import hello.HelloService;
public class HelloServiceImpl implements HelloService { public void sayHello() { System.out.println(" === S1서비스의 sayHello() 메소드 호출됨."); } }
OSGi Service Platform Release 4 의 기본 개념을 이해할 수 있다.
OSGi 소개
OSGi 는 OSGi Alliance 에 의해 만들어진 Java 기반 원격 관리 플랫폼이다.
OSGi 의 특징은 다음과 같이 정리될 수 있다.
Java 플랫폼을 위한 모듈 시스템
Visibility Rules 과 Bundle 들간의 Dependency 관리 및 Versioning 등의 기능 포함.
동적 플랫폼
Bundle 의 Installing, starting, stopping, updating, uninstalling 같은 모든 동적인 동작이 모두 JVM 이 실행중에 일어남.
Service Oriented
Service 는 JVM 이 실행중일 때 등록되고 쓰여질 수 있음.
OSGi 의 핵심은 Application Life Cycle Management 모델에 관한 Framework 과 Service Registry 와 Execution Environment 와 Module 들이다. 이를 기반으로 많은 수의 OSGi 레이어와 API, 각종 서비스들이 정의되어 있다.
OSGi 를 통해 얻을 수 있는 이익은 다음과 같다.
JAR file hell 을 피할 수 있음.
Reuse code "out of the box"
Simplifies multi-team projects
Enables smaller systems
Manages deployments local or remotely
Extensive tool support
No lock in, many providers of core technology
including many open source
Very high adoption rate
OSGi 시작과 현재 상태
OSGi 는 처음에 다음과 같은 문제점들에 대한 대응을 하기 위해 시작되었다.
짧아진 제품주기, 폭증한 요구사항, H/W 와 O/S 에 따른 제품의 커스터마이징 범위 증가 등에 의해 S/W 복잡성이 증가했으며, 이로 인한 비용증가가 개발비용증가의 상당부분을 차지하고 있음.
표준화된 Library 들을 이용해서 많은 기능들을 구현해왔으나 이들 Library 를 사용하는데에 따르는 사용상 문제점도 같이 많아지고 있음.
UI 던 내부로직이던 매우 복잡해진 S/W 로 인해 테스팅 비용도 같이 상승했음.
이러한 문제점들은 여러 S/W 개발부품들을 통합하는 관점에 대한 표준화의 요구를 가져왔으며, OSGi 는 이러한 문제점에 대해 다음과 같은 해결책을 제시한다.
Java 가 상이한 플랫폼상에서 동일한 인터페이스를 제공하는 추상화 플랫폼을 만들듯이, OSGi 는 재사용 가능하고 상호작용이 되는 작은 컴포넌트들을 서로 엮어서 Application 을 만들어내는 기본적인 기능의 표준을 제공함.
OSGi 는 시스템 재시작이 없이도 다양한 네트워크상의 장치들간의 상호구성상태를 바꿀 수 있는 기능을 제공함. 이를 위해 모든 상호작용을 위해 컴포넌트 상호간을 동적으로 탐색하게 할 수 있는 서비스 지향적인 아키텍처를 제공해서 상호 의존성을 최소화함.
OSGi 기술에 의해 미리 만들어지고 테스트된 컴포넌트라면 필드상에서 바로 쓰일 수 있을 정도의 신뢰성을 제공함.
2000년 5월에 Release 1 이 발표되었고, 2007년 5월에 Release 4.1 이 릴리스되었다.
OSGi 를 이용해보기 위해 필요한 Core Framework 런타임으로는 Eclipse 의 Equinox 가 있다. Equinox 는 OSGi Service Platform Release 4 의 Core Framework 과 기타 부수적인 서비스들을 구현하고 있다.
OSGi Service Platform
OSGi Service Platform 은 Core Specification 과 Service Compendium 으로 구성된다.
Core Specification 은 OSGi Service Platform 을 규정하며, 필수 서비스 집합인 Framework Services 을 규정한다. 이를 구현한 것이 Framework 혹은 Core Framework 이다.
Service Compendium 은 기타 서비스들을 규정한다.
OSGi Service Platform 의 Architecture 는 다음 그림과 같다.
OSGi Core Framework
Bundle 을 위한 표준화된 기본 환경을 제공한다.
Framework 은 다음과 같은 Layer 로 나뉜다.
L0: Execution 환경은 Java 런타임에서 Bundle 이 실행에 대한 실행환경 규약이다. 애초에 Java ME 에만 초점이 맞춰져 있었지만, 이제는 Java SE 나 Java EE 로 확대되었다. 애초의 실행환경은 다음과 같이 규정되었었다.
Small Devices
Collaboration model
Continously up and running VM
Life cycle management
L1: Modules 레이어는 클래스 로딩 정책을 정의한다. Java 를 하위레이어로 두고 있으면서 기본 클래스패스 외에 모듈간의 상호조율에 대한 고려가 되어 있는 내부 클래스패스를 추가로 정의한다. 이것은 보안시스템, 공개되지 않은 시스템에 대한 배포등을 지원한다.
L2: Life Cycle Management 레이어는 Bundle 들을 동적으로 설치, 시작, 중지, 갱신, 제거시킨다. Bundle 은 기본적으로 Modules 레이어의 클래스 로딩에 의존하지만, 여기에 추가해서 Life Cycle Management 에서 실행중의 관리를 위한 기능을 Bundle 에 추가시킨다. Life Cycle 은 광범위한 의존성 메커니즘을 사용하며, 보안시스템으로 보호되어서 가상적으로 바이러스의 공격으로부터 안전하게 한다.
L3: Service Registry 는 계정기반으로 클래스들을 bundle 간에 안전하게 동적으로 공유할 수 있게 해서 설치와 제거를 안전하게 지원한다.
Framework Services
Core Framework 은 다음과 같은 Framework Service 들을 제공하며, 이들은 Framework 내에 포함되어 있다.
Permission Admin
Bundle 의 Permission 을 설정하는 서비스이다.
Package Admin
Bundle 들은 Class 와 Resource 를 포함한 Package 를 공유하는데, Bundle 들이 갱신되면 이 공유정보도 갱신되어야 한다. Package Admin 서비스가 이러한 정보를 관리한다.
Start Level
Bundle 들간의 시작에 관한 우선순위를 조정해서 동시에 혹은 선후로 시작해야 하는 Bundle 들의 집합을 정의한다.
URL Handler
Java 에는 URL Handling 에 대한 Provider Model 을 제공하지만, 이것은 OSGi 같은 Collaborative 한 환경에는 맞지 않는다. URL Handler 서비스는 Bundle 에게 새롭고 변형된 형태의 프로토콜을 다룰 수 있게 해준다.
OSGi Service Compendium
OSGi 에 참여하는 업체들은 OSGi Framework 상에 많은 서비스들을 정의하는데, 이 서비스들은 Interface 로 노출되며, Bundle 은 이 Interface 를 구현함으로써 해당 서비스로서 Service Registry 에 등록될 수 있다. 서비스의 클라이언트는 Service Registry 로부터 서비스를 검색할 수 있고, 서비스가 등록되거나 사라졌을 때에 대한 조치도 취할 수 있다.
이런 방식은 웹서비스와 비슷하기도 하지만, 웹서비스가 HTTP 로 연결되는 것과는 달리 OSGi 에서는 메소드 호출을 통해 이루어지는 차이점이 있다.
다음에 나오는 내용은 OSGi Release 4 에서 Framework Services 들을 제외한 나머지 서비스들에 대한 Specification 이다.
Log Service
정보와 경고, 디버그 정보나 에러의 기록을 담당한다. Log System 은 최초 수신처가 되며, 해당 로그에 관심있는 Bundle 들에게 해당 로그를 보낸다.
Http Service
Servlet Runner 서비스이다. OSGi 의 동적인 업데이트 기능을 통해 Http Service 는 재시작이 필요없고 원격으로도 새 Servlet 으로 업데이트가 가능한 웹서버가 된다.
Configuration Admin Service
설정관련 기능을 제공한다.
Metatype Service
Bundle 이 사용하는 각 Property 에 대해 컴퓨터가 이해할 수 있는 포맷으로 기술하는 기능을 제공한다.
Preferences Service
Windows 의 Registry 나 Java 의 Preferences 클래스와 같이 프로퍼티를 계층적으로 관리하는 역할을 한다.
User Admin Service
사용자에 대한 인증과 허용작업을 한다.
Wire Admin Service
설치가 된 후에라도 Bundle 들간에 상호접속정보를 Configuration File 로부터 읽어들여서 Bundle 들을 서로 연결해준다.
IO Connector Service
CDC/CLDC 의 javax.microedition.io 패키지를 서비스로 제공한다.
UPnP Deivce Service
Universal Plug and Play 은 가전제품의 통합표준이다. OSGi UPnP Service 는 UPnP 네트워크상의 장치를 Service Registry 에 매핑시킨다. 또는 OSGi 서비스들을 UPnP Network 에 매핑할 수도 있다.
Declarative Service
Service 를 publish/find/bind 할 때 필요한 정보를 기술하는 서비스를 제공한다.
Event Admin Service
많은 OSGi 이벤트들은 특정한 인터페이스를 가지고 있어서 일반적으로 이벤트를 수신하거나 거르기가 쉽지 않다. Event Admin 은 토픽기반 이벤트 매커니즘같은 일반화된 방식을 제공하며, framework 과 service 간의 이벤트 매핑기능도 제공한다.
Application Admin Service
OSGi Application 들이 각각 필요로 하는 실행환경에 대한 관리를 담당하는 서비스이다.
DMT Admin Service
OMA 는 OMA DM (Device Management) 규격을 DMT (Device Management Tree) Admin 서비스로 제공하고 있다.
Monitor Admin Service
Bundle 이 어떻게 상태정보를 제공해야 하는지와 관리 기능을 가진 Bundle 이 어떻게 각 Bundle 의 상태정보 위치를 알아내고 상태정보를 읽거나 설정할 수 있는지를 관리하는 서비스를 제공한다.
XML Parser Service
JAXP 를 보다 더 쉽고 편리하게 이용하게 해준다.
이 밖에 다음과 같은 내용을 규정하고 있다.
Device Access
Plug and Play 에서처럼 해당 Device 에 적절한 Driver 를 찾고 이를 구현하는 Bundle 을 다운로드하는 것을 관리한다.
Initial Provisioning
OSGi Service Platform 은 Management Agent 를 통해 원격 관리하는데, Management Agent 에 대한 내용을 규정한다.
Deployment Admin
OSGi 에서 배포파일포맷은 JAR/ZIP 이다. 여기에 추가해서 Deployment Admin 은 Deployment Admin 은 Deployment Package 를 제공하는데, 이것은 Bundle 들을 각각의 리소스와 같이 묶어서 한 번에 설치와 제거가 같이 될 수 있도록 한다.
Auto Configuration
Bundle 이 자동 구성될 수 있게 하기 위한 내용을 규정한다.
Foreign Application Access
OSGi Application 이 아닌 Application 과 연동하기 위한 내용을 규정한다.
Service Tracker
OSGi Service Platform 은 재기동없이 Bundle 을 관리할 수 있는데, 이를 위해 Bundle 들간의 Dependency 를 추적하는 내용을 규정한다.
Position
OSGi Application 의 물리적 위치정보를 제공하는 내용을 규정한다. GPS 와 호환될 수 있다.
Measurement and State
OSGi Bundle 을 계측할 수 있는 내용을 규정한다.
Execution Environment
OSGi/Minimum-1.1 실행환경과 CDC-1.1/Foundation-1.1 실행환경에 대한 내용을 규정한다.