[ OSGi ] Spring DM 1, 2, 3 에서 OSGi에서 Spring을 이용한 서비스 등록과 Annotation 사용을 보았다


이번에는 이것을 Eclipse 에서 바로 실행을 해보자 .



Run Configurations... 를 선택한다. 


OSGi Framework를 더블클릭 하면 밑에 New_configuration이 생긴다.

OSGi 구동시 필요한 plugin 들을 선택하고 Run을 한다.


Console 창에 다음과 같이 나오면 성공이다.


Posted by jabsiri
TAG Equinox, OSGi

[ OSGi ] 6 - Spring DM 3

JAVA 2014.08.28 21:16

[ OSGi ] 5 - Spring DM 2 에서 Spring DM을 이용해서 service 등록하는 내용을 봤다.


HelloWorldOSGiSub Project의 Activator(SubActivator.java)를 대신 하는 Spring annotation 과 DI를 적용 해보자.


Target Platform 추가

1. Spring에서 필요한 library project로 등록


lib로 프로젝트를 하나 만든다. 



lib로 필요한 library를 넣는다. ( 여기의 lib 파일은 [ OSGi ] 4 - Spring DM 1 에서 설명한 lib이다. )


2. 그럼 이제 해당 lib 들을 target platform에 설정을 한다. 

Window > Preferences 를 클릭하여 Plug-in Development > Target Platform을 선택한다. 

아래의 화면에서 Edit...를 선택한다.


Add... 선택후 Directory를 선택한다.

             


이전에 만든 lib 경로를 지정하고 등록된 것을 확인한다.

   



Content Tab에 들어가서 Group by : 를 Location으로 선택하고 


lib Project 밑의 파일들을 모두 선택한다. 


그리고 Spring 3.2.9 를 사용 할것 이므로 "spring"으로 검색 후 4.0.2 부분의 선택을 해제한다. 



Activator  제거 Spring Annotation 추가 

SubSpringDMStarter.java, spring.xml을 추가한다. 


1. MANIFEST.MF 에서 Bundle-Activator 부분을 지우고 밑에 빨강박스의 내용을 추가한다. 


더보기


2. SubActivator를 대신할 kr.co.jabsiri.helloworldosgisub.SubSpringDMStarter.java 를 만든다.

여기서 BundleContext 를 @Autowired를 통해 주입 받는 것에 주목하자.

(Activator에서는 start method의 parameter로 받았었다. )

src


2. META-INF/spring/spring.xml을 만든다.


source




배포 & 실행

* 참고로 이전에 배포한 내용을 지워서 다시 plugin들을 install 할 것 이다.


1. HelloWorldOSGiSub을 배포한다.

2. HelloWorldOSGiSub을 update 한 후 start 를 해보자

osgi> ss

"Framework is launched."



id      State       Bundle

0       ACTIVE      org.eclipse.osgi_3.10.0.v20140606-1445

1       ACTIVE      org.eclipse.equinox.common_3.6.200.v20130402-1505

2       ACTIVE      org.eclipse.equinox.console_1.1.0.v20140131-1639

3       ACTIVE      org.apache.felix.gogo.shell_0.10.0.v201212101605

4       ACTIVE      org.apache.felix.gogo.command_0.10.0.v201209301215

5       ACTIVE      org.apache.felix.gogo.runtime_0.10.0.v201209301036

6       ACTIVE      com.springsource.org.aopalliance_1.0.0

7       ACTIVE      org.apache.commons.logging_1.1.3

8       ACTIVE      log4j_1.2.17

9       ACTIVE      org.apache.servicemix.bundles.spring-aop_3.2.9.RELEASE_1

10      ACTIVE      org.apache.servicemix.bundles.spring-beans_3.2.9.RELEASE_1

11      ACTIVE      org.apache.servicemix.bundles.spring-context_3.2.9.RELEASE_1

12      ACTIVE      org.apache.servicemix.bundles.spring-context-support_3.2.9.RELEASE_1

13      ACTIVE      org.apache.servicemix.bundles.spring-core_3.2.9.RELEASE_1

14      ACTIVE      org.apache.servicemix.bundles.spring-expression_3.2.9.RELEASE_1

15      ACTIVE      slf4j.api_1.7.7

                    Fragments=16

16      RESOLVED    slf4j.log4j12_1.7.7

                    Master=15

17      ACTIVE      org.springframework.osgi.extensions.annotations_1.2.1

18      ACTIVE      org.springframework.osgi.core_1.2.1

19      ACTIVE      org.springframework.osgi.extender_1.2.1

20      ACTIVE      org.springframework.osgi.io_1.2.1

21      ACTIVE      sample.HelloWorldOSGi_1.0.0

22      ACTIVE      HelloWorldOSGiSpringDM_1.0.0

23      RESOLVED    sample.HelloWorldOSGiSub_1.0.0

osgi> update 23


osgi> start 23

osgi> print string : I am sub spring dm !!!

spring dm service print string : I am sub spring dm !!!



보는 바와 같이 Activator에서 출력하는 내용 대신에 "spring dm service print string : I am sub spring dm !!!"이 출력된 것을 볼수 있다.


이것으로 Activator를 상속 받을 필요도 없고 Spring의 DI를 사용하여 BundleContext를 얻어 사용할수 있게 되었다.



첨부 1 : HelloWorldOSGi plugin Eclipse Project

HelloWorldOSGi_6.zip



첨부 2 : OSGi Framework

plugins_osgi_6.zip











'JAVA' 카테고리의 다른 글

[Mybaits-TIP] XML에서 static method 호출 하기와  (1) 2016.04.01
[ OSGi ] 7 - OSGi Eclipse 실행  (0) 2014.08.29
[ OSGi ] 6 - Spring DM 3  (0) 2014.08.28
[ OSGi ] 5 - Spring DM 2  (0) 2014.08.26
[ OSGi ] 4 - Spring DM 1  (0) 2014.08.25
[ OSGi ] 3 - OSGi plugin 의존 관계  (0) 2014.08.20
Posted by jabsiri
TAG Equinox, OSGi

[ OSGi ] 5 - Spring DM 2

JAVA 2014.08.26 18:03



[ OSGi ] 4 - Spring DM 1 에서 Spring 관련 bundle을 올리고 Activator 대신 spring.xml에 설정한 init-method, destory-method 사용을 알아봤다.


여기서는 Spring 을 이용해서 OSGi의 Service에 등록하는 것을 해보겠다. 
( 앞에서도 말했지만 일반적인 Service 등록은 
http://xguru.net/tag/osgi 에서 OSGi 시작하기 4OSGi 사직하기 5 를 참고하자. )




서비스에 등록할 인터페이스 생성

1. interface 생성

HelloWorldOSGiSpringDM  프로젝트에 HelloWorldOSGiSpringDMPrinter.java와 HelloWorldOSGiSpringDMPrinterImpl.java 파일을 생성한다. 



2. code 작성

kr.co.jabsiri.helloworldosgi.springdm.HelloWorldOSGiSpringDMPrinter.java

더보기


kr.co.jabsiri.helloworldosgi.springdm.HelloWorldOSGiSpringDMPrinterImpl.java

더보기



3. spring.xml 내용 추가

더보기



4. MANIFEST.MF 수정

Export-Package: kr.co.jabsiri.helloworldosgi.springdm.service 를 추가하자

더보기



등록된 서비스 사용

[ OSGi ] 3 - OSGi plugin 의존 관계 에서 작성한 HelloWorldOSGiSub 프로젝트에서 위에서 작성한 SubActivator.java 에서 helloWorldOSGiSpringDMPrinter 서비스를 호출해 보도록 하자.


1. MANIFEST.MF

Import-Package 부분에 kr.co.jabsiri.helloworldosgi.springdm.service 를 추가한다.

더보기


2. 등록된 서비스 사용 

SubActivator.java 에 빨간박스 부분의 코드를 추가하자


더보기

이 코드는 서비스로 등록된 내용을 가져와 사용하는 것이다.



배포 & 실행

1. HelloWorldOSGiSpringDM과 sample.HelloWorldOSGiSub 두 프로젝트를 Export 한다. 



2. HelloWorldOSGiSpringDM_1.0.0.jar install 

install file:HelloWorldOSGiSpringDM_1.0.0.jar 로 plugin을 install 시키고 

b 22로 plugin의 상세 정보를 확인하면 밑에 빨간색 부분처럼 HelloWorldOSGiSpringDMPrinter가 서비스에 등록되어 있는 모습을 볼수 있다.


osgi> install file:HelloWorldOSGiSpringDM_1.0.0.jar

Bundle id is 22

Location             file:HelloWorldOSGiSpringDM_1.0.0.jar

State                2

Bundle                  22|Installed  |    1|HelloWorldOSGiSpringDM (1.0.0)

Version              1.0.0

SymbolicName         HelloWorldOSGiSpringDM

BundleContext        null

Module               osgi.identity; osgi.identity="HelloWorldOSGiSpringDM"; type="osgi.bundle"; version:Version="1.0.0" [id=22]

ServicesInUse        null

RegisteredServices   null

BundleId             22

LastModified         1409211674925

Headers               Bundle-ManifestVersion = 2

 Bundle-Name = HelloWorldOSGiSpringDM

 Bundle-RequiredExecutionEnvironment = JavaSE-1.6

 Bundle-SymbolicName = HelloWorldOSGiSpringDM

 Bundle-Version = 1.0.0

 Export-Package = kr.co.jabsiri.helloworldosgi.springdm.service

 Manifest-Version = 1.0 



osgi> start 22

osgi> spring dm start


osgi> b 22

HelloWorldOSGiSpringDM_1.0.0 [22]

  Id=22, Status=ACTIVE      Data Root=C:\develop\OSGi\sample\plugins\configuration\org.eclipse.osgi\22\data

  "Registered Services"

    {kr.co.jabsiri.helloworldosgi.springdm.service.HelloWorldOSGiSpringDMPrinter}={org.springframework.osgi.bean.name=helloWorldOSGiSpringDMPrinter, Bundle-SymbolicName=HelloWorldOS

GiSpringDM, Bundle-Version=1.0.0, service.id=49, service.bundleid=22, service.scope=bundle}

    {org.springframework.osgi.context.DelegatedExecutionOsgiBundleApplicationContext, org.springframework.osgi.context.ConfigurableOsgiBundleApplicationContext, org.springframework.

context.ConfigurableApplicationContext, org.springframework.context.ApplicationContext, org.springframework.context.Lifecycle, java.io.Closeable, org.springframework.beans.factory.L

istableBeanFactory, org.springframework.beans.factory.HierarchicalBeanFactory, org.springframework.context.MessageSource, org.springframework.context.ApplicationEventPublisher, org.

springframework.core.io.support.ResourcePatternResolver, org.springframework.beans.factory.BeanFactory, org.springframework.core.io.ResourceLoader, java.lang.AutoCloseable, org.spri

ngframework.beans.factory.DisposableBean}={org.springframework.context.service.name=HelloWorldOSGiSpringDM, Bundle-SymbolicName=HelloWorldOSGiSpringDM, Bundle-Version=1.0.0, service

.id=50, service.bundleid=22, service.scope=singleton}

  Services in use:

    {org.springframework.beans.factory.xml.NamespaceHandlerResolver}={spring.osgi.core.bundle.id=18, spring.osgi.core.bundle.timestamp=1409042843468, service.id=47, service.bundleid

=19, service.scope=singleton}

    {org.xml.sax.EntityResolver}={spring.osgi.core.bundle.id=18, spring.osgi.core.bundle.timestamp=1409042843468, service.id=48, service.bundleid=19, service.scope=singleton}

    {org.osgi.service.packageadmin.PackageAdmin}={service.ranking=2147483647, service.pid=0.org.eclipse.osgi.internal.framework.legacy.PackageAdminImpl, service.vendor=Eclipse.org -

 Equinox, service.id=11, service.bundleid=0, service.scope=singleton}

  Exported packages

    kr.co.jabsiri.helloworldosgi.springdm.service; version="0.0.0"[exported]

  No imported packages

  No fragment bundles

  No required bundles


3. sample.HelloWorldOSGiSub_1.0.0.jar install

그럼 서비스에 등록된 내용을 사용하는 sample.HelloWorldOSGiSub_1.0.0.jar를 install 해보자


install file:sample.HelloWorldOSGiSub_1.0.0.jar

osgi> install file:sample.HelloWorldOSGiSub_1.0.0.jar

Bundle id is 23

Location             file:sample.HelloWorldOSGiSub_1.0.0.jar

State                2

Bundle                  23|Installed  |    1|sample.HelloWorldOSGiSub (1.0.0)

LastModified         1409212486067

Headers               Bundle-Activator = kr.co.jabsiri.helloworldosgisub.SubActivator

 Bundle-ManifestVersion = 2

 Bundle-Name = HelloWorldOSGiSub

 Bundle-RequiredExecutionEnvironment = JavaSE-1.6

 Bundle-SymbolicName = sample.HelloWorldOSGiSub

 Bundle-Version = 1.0.0

 Import-Package = org.osgi.framework;version="1.3.0",kr.co.jabsiri.helloworldosgi,kr.co.jabsiri.helloworldosgi.springdm.service

 Manifest-Version = 1.0



Version              1.0.0

Module               osgi.identity; osgi.identity="sample.HelloWorldOSGiSub"; type="osgi.bundle"; version:Version="1.0.0" [id=23]

RegisteredServices   null

ServicesInUse        null

BundleContext        null

SymbolicName         sample.HelloWorldOSGiSub

BundleId             23



osgi> start 23

print string : I am sub activator !!!

spring dm service print string : I am sub activator !!!


sample.HelloWorldOSGiSub 에서는 sample.HelloWorldOSGi도 사용하고 있으니 이것도 install을 시킨다.

install file:sample.HelloWorldOSGi_1.0.0.jar

osgi> install file:sample.HelloWorldOSGi_1.0.0.jar

Bundle id is 24

Location             file:sample.HelloWorldOSGi_1.0.0.jar

State                2

Bundle                  24|Installed  |    1|sample.HelloWorldOSGi (1.0.0)

LastModified         1409212573947

Headers               Bundle-Activator = kr.co.jabsiri.helloworldosgi.Activator

 Bundle-ManifestVersion = 2

 Bundle-Name = HelloWorldOSGi

 Bundle-RequiredExecutionEnvironment = JavaSE-1.6

 Bundle-SymbolicName = sample.HelloWorldOSGi

 Bundle-Version = 1.0.0

 Export-Package = kr.co.jabsiri.helloworldosgi

 Import-Package = org.osgi.framework;version="1.3.0"

 Manifest-Version = 1.0



Version              1.0.0

Module               osgi.identity; osgi.identity="sample.HelloWorldOSGi"; type="osgi.bundle"; version:Version="1.0.0" [id=24]

RegisteredServices   null

ServicesInUse        null

BundleContext        null

SymbolicName         sample.HelloWorldOSGi

BundleId             24



그리고 start 23 을 하자 ( 23은 sample.HelloWorldOSGiSub 의 bundle 번호 )

osgi> start 23

print string : I am sub activator !!!

spring dm service print string : I am sub activator !!!

그럼. 위와같이 HelloWorldOSGiSpringDM의 HelloWorldOSGiSpringDMPrinter.java에 정의한 printer method가 실행된 것을 확인한다. 



첨부 1 : HelloWorldOSGi plugin Eclipse Project 

HelloWorldOSGi_5.zip



첨부 2 : OSGi Framework 

plugins_osgi_5.zip


'JAVA' 카테고리의 다른 글

[ OSGi ] 7 - OSGi Eclipse 실행  (0) 2014.08.29
[ OSGi ] 6 - Spring DM 3  (0) 2014.08.28
[ OSGi ] 5 - Spring DM 2  (0) 2014.08.26
[ OSGi ] 4 - Spring DM 1  (0) 2014.08.25
[ OSGi ] 3 - OSGi plugin 의존 관계  (0) 2014.08.20
[ OSGi ] 2 - OSGi plugin project  (2) 2014.08.19
Posted by jabsiri
TAG Equinox, OSGi

[ OSGi ] 4 - Spring DM 1

JAVA 2014.08.25 15:50


[ OSGi ] 3 - OSGi plugin 의존 관계 에서 서로 다른 Plugin 간의 Class 사용을 해보았다. ( Import-Package, Export-Package )

그런데 이런 단순한 내용 뿐만 아니라 Spring의 핵심 기능인 DI는 IoC중의 한 종류인데 OSGi framework 에서도 IoC를 설계하여 적용 할수 있다.

바로 OSGi의 서비스 등록인데 

이는 http://xguru.net/tag/osgi 에서 OSGi 시작하기 4OSGi 사직하기 5 에 잘 정리 되어 있다. 

꼭 읽어봐야함!!! 



여기서는 OSGi에서의 Spring DM을 이용한 서비스 등록을 보도록 하겠다. 

Spring DM을 할용해서 OSGi 서비스의 등록을 간편하게 할 수 있다. 


< 참고 >

Spring DM은 현재 spring.io 더이상 진행 하지 않는다.

spring.io에서 eclipse.org에게 SpringDM Project을 기부하면서 이름이 blueprint로 바뀌었다. 

여기서는 예전의 SpringDM을 사용해서 진행을 하도록 하겠다.


Spring을 OSGi에서 사용하기 위해서는 OSGi에서 사용할수 있는 Spring bundle 이 필요한데 Spring의 최신 버전은 OSGi Bundle로 사용할수 있게 더이상 module을 제공하지 않는다.

하지만 servicemix 라는 곳에서 이러한 Spring을 버전별로 OSGi bundle에서 사용할수 있도록 수정하여 maven repository를 제공하고 있다.

http://mvnrepository.com/artifact/org.apache.servicemix.bundles

여기에는 Spring 뿐만 아니라 OSGi에서 사용할수 있도록 각종 library를 제공하고 있다.


이 글을 쓰는 시점에는 Spring 4.0.5 version 까지 제공하고있다. ( Spring은 4.0.6 까지 배포됨. )


이 글에서는 Spring 3.2.9 RELEASE를 이용 한다.


필요 Library

1. spring 관련 libary 추가 

Spring DM을 쓰기 위해서는 다음과 같은 library가 기본으로 필요하다.

com.springsource.org.aopalliance-1.0.0.jar

commons-logging-1.1.3.jar

log4j-1.2.17.jar

org.apache.servicemix.bundles.spring-aop-3.2.9.RELEASE_1.jar

org.apache.servicemix.bundles.spring-beans-3.2.9.RELEASE_1.jar

org.apache.servicemix.bundles.spring-context-3.2.9.RELEASE_1.jar

org.apache.servicemix.bundles.spring-context-support-3.2.9.RELEASE_1.jar

org.apache.servicemix.bundles.spring-core-3.2.9.RELEASE_1.jar

org.apache.servicemix.bundles.spring-expression-3.2.9.RELEASE_1.jar

slf4j-api-1.7.7.jar

slf4j-log4j12-1.7.7.jar

spring-osgi-annotation-1.2.1.jar

spring-osgi-core-1.2.1.jar

spring-osgi-extender-1.2.1.jar

spring-osgi-io-1.2.1.jar

Library 첨부 : 

spring_lib.zip


해당 library 를 plugins 밑에 "spring" folder를 만들어서 넣어두자


최종적인 모습은 다음과 같다.

sample 

   |-- plugins

            |-- org.apache.felix.gogo.command_xxx.jar

            |-- org.apache.felix.gogo.runtime_xxx.jar

            |-- org.apache.felix.gogo.shell_xxx.jar

            |-- org.eclipse.equinox.common_xxx.jar

            |-- org.eclipse.equinox.console_xxx.jar

            |-- org.eclipse.osgi_xxx.jar

            |-- sample.HelloWorldOSGi_1.0.0.jar

            |-- sample.HelloWorldOSGiSub_1.0.0.jar

            |-- spring

                     |-- com.springsource.org.aopalliance-1.0.0.jar

                     |-- commons-logging-1.1.3.jar

                     |-- log4j-1.2.17.jar

                     |-- org.apache.servicemix.bundles.spring-aop-3.2.9.RELEASE_1.jar

                     |-- org.apache.servicemix.bundles.spring-beans-3.2.9.RELEASE_1.jar

                     |-- org.apache.servicemix.bundles.spring-context-3.2.9.RELEASE_1.jar

                     |-- org.apache.servicemix.bundles.spring-context-support-3.2.9.RELEASE_1.jar

                     |-- org.apache.servicemix.bundles.spring-core-3.2.9.RELEASE_1.jar

                     |-- org.apache.servicemix.bundles.spring-expression-3.2.9.RELEASE_1.jar

                     |-- slf4j-api-1.7.7.jar

                     |-- slf4j-log4j12-1.7.7.jar

                     |-- spring-osgi-annotation-1.2.1.jar

                     |-- spring-osgi-core-1.2.1.jar

                     |-- spring-osgi-extender-1.2.1.jar

                     |-- spring-osgi-io-1.2.1.jar

   |-- configuration

            |-- config.ini 


2. config.ini를 다음과 같이 수정한다.

#Eclipse Runtime Configuration File

osgi.bundles=org.eclipse.equinox.common_3.6.200.v20130402-1505.jar@2:start,\

org.eclipse.equinox.console_1.1.0.v20140131-1639.jar@start,\

org.apache.felix.gogo.shell_0.10.0.v201212101605.jar@start,\

org.apache.felix.gogo.command_0.10.0.v201209301215.jar@start,\

org.apache.felix.gogo.runtime_0.10.0.v201209301036.jar@start,\

spring/com.springsource.org.aopalliance-1.0.0.jar@start,\

spring/commons-logging-1.1.3.jar@start,\

spring/log4j-1.2.17.jar@start,\

spring/org.apache.servicemix.bundles.spring-aop-3.2.9.RELEASE_1.jar@start,\

spring/org.apache.servicemix.bundles.spring-beans-3.2.9.RELEASE_1.jar@start,\

spring/org.apache.servicemix.bundles.spring-context-3.2.9.RELEASE_1.jar@start,\

spring/org.apache.servicemix.bundles.spring-context-support-3.2.9.RELEASE_1.jar@start,\

spring/org.apache.servicemix.bundles.spring-core-3.2.9.RELEASE_1.jar@start,\

spring/org.apache.servicemix.bundles.spring-expression-3.2.9.RELEASE_1.jar@start,\

spring/slf4j-api-1.7.7.jar@start,\

spring/slf4j-log4j12-1.7.7.jar,\

spring/spring-osgi-annotation-1.2.1.jar@start,\

spring/spring-osgi-core-1.2.1.jar@start,\

spring/spring-osgi-extender-1.2.1.jar@start,\

spring/spring-osgi-io-1.2.1.jar@start

osgi.bundles.defaultStartLevel=4


3. OSGi 실행 후 ss 명령어를 입력하면 다음과같이 나오면 성공한 것이다.

C:\develop\OSGi\sample\plugins>java -Declipse.ignoreApp=true -jar org.eclipse.osgi_3.10.0.v20140606-1445.jar -console -consoleLog

log4j:WARN No appenders could be found for logger (org.springframework.osgi.exte

nder.internal.activator.ContextLoaderListener).

log4j:WARN Please initialize the log4j system properly.

log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.

osgi> ss

"Framework is launched."



id      State       Bundle

0       ACTIVE      org.eclipse.osgi_3.10.0.v20140606-1445

1       ACTIVE      org.eclipse.equinox.common_3.6.200.v20130402-1505

2       ACTIVE      org.eclipse.equinox.console_1.1.0.v20140131-1639

3       ACTIVE      org.apache.felix.gogo.shell_0.10.0.v201212101605

4       ACTIVE      org.apache.felix.gogo.command_0.10.0.v201209301215

5       ACTIVE      org.apache.felix.gogo.runtime_0.10.0.v201209301036

6       ACTIVE      com.springsource.org.aopalliance_1.0.0

7       ACTIVE      org.apache.commons.logging_1.1.3

8       ACTIVE      log4j_1.2.17

9       ACTIVE      org.apache.servicemix.bundles.spring-aop_3.2.9.RELEASE_1

10      ACTIVE      org.apache.servicemix.bundles.spring-beans_3.2.9.RELEASE_1

11      ACTIVE      org.apache.servicemix.bundles.spring-context_3.2.9.RELEASE_1


12      ACTIVE      org.apache.servicemix.bundles.spring-context-support_3.2.9.RELEASE_1

13      ACTIVE      org.apache.servicemix.bundles.spring-core_3.2.9.RELEASE_1

14      ACTIVE      org.apache.servicemix.bundles.spring-expression_3.2.9.RELEASE_1

15      ACTIVE      slf4j.api_1.7.7

                    Fragments=16

16      RESOLVED    slf4j.log4j12_1.7.7

                    Master=15

17      ACTIVE      org.springframework.osgi.extensions.annotations_1.2.1

18      ACTIVE      org.springframework.osgi.core_1.2.1

19      ACTIVE      org.springframework.osgi.extender_1.2.1

20      ACTIVE      org.springframework.osgi.io_1.2.1

osgi> 


제대로 나오지 않으면 "plugins\configuration 폴더"에서 "config.ini"를 제외하고 모든 폴더와 파일을 지우고 다시 한번 해보자.





프로젝트 생성

다음과 같이 프로젝트를 생성한다.



이번에는 Options의 "Generate an activator a Java class that controls the plug-in's life cycle" 체크 박스를 선택하지 않는다.



프로젝트를 생성후 Spring 프로젝트로 변경을 해준다.



kr.co.jabsiri.helloworldosgi.springdm.HelloWorldOSGiSpringDMStarter.java 를 만들고 다음과 같이 작성한다. 


더보기


이 클래스가 이전에 봐왔던 Activator를 역할을 대신 하게 된다. 

META-INF 폴더 밑에 spring.xml 파일을 만들고 다음과 같이 작성한다.



spring.xml 내용

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:osgi="http://www.springframework.org/schema/osgi"

xsi:schemaLocation="http://www.springframework.org/schema/beans 

http://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/osgi

        http://www.springframework.org/schema/osgi/spring-osgi.xsd">

<bean id="helloOSGiSpringDM" 

class="kr.co.jabsiri.helloworldosgi.springdm.HelloWorldOSGiSpringDMStarter" 

init-method="start" destroy-method="stop" />

</beans>

init-method 는 activator의 start와 역활을 하는 메소드를 지정하며

destroy-method는 activator의 stop 역활을 하는 메소드를 지정한다. 


배포 

프로젝 생성에 코드까지 생성 했으면 배포후 install을 해보자 ( 배포는 앞의 강좌를 참고 )

osgi> install file:HelloWorldOSGiSpringDM_1.0.0.jar

Bundle id is 21

Location             file:HelloWorldOSGiSpringDM_1.0.0.jar

State                2

Bundle                  21|Installed  |    1|HelloWorldOSGiSpringDM (1.0.0)

Version              1.0.0

LastModified         1409042885287

Headers               Bundle-ManifestVersion = 2

 Bundle-Name = HelloWorldOSGiSpringDM

 Bundle-RequiredExecutionEnvironment = JavaSE-1.6

 Bundle-SymbolicName = HelloWorldOSGiSpringDM

 Bundle-Version = 1.0.0

 Manifest-Version = 1.0



BundleContext        null

BundleId             21

SymbolicName         HelloWorldOSGiSpringDM

RegisteredServices   null

ServicesInUse        null

Module               osgi.identity; osgi.identity="HelloWorldOSGiSpringDM"; type="osgi.bundle"; version:Version="1.0.0" [id=21]


osgi> start 21

osgi> spring dm start


osgi> stop 21

spring dm stop

osgi> 







첨부 1 : HelloWorldOSGi plugin Eclipse Project

HelloWorldOSGi_4.zip



첨부 2 : OSGi Framework

plugins_osgi_4.zip




'JAVA' 카테고리의 다른 글

[ OSGi ] 6 - Spring DM 3  (0) 2014.08.28
[ OSGi ] 5 - Spring DM 2  (0) 2014.08.26
[ OSGi ] 4 - Spring DM 1  (0) 2014.08.25
[ OSGi ] 3 - OSGi plugin 의존 관계  (0) 2014.08.20
[ OSGi ] 2 - OSGi plugin project  (2) 2014.08.19
[ OSGi ] 1 - OSGi 기초  (0) 2014.06.24
Posted by jabsiri
TAG Equinox, OSGi


[ OSGi ] 2 - OSGi Plugin Project 에서 OSGi에서 구동될 Plugin을 개발할 프로젝트 생성과 install, start를 해보았다.


여기서는 여러 Plugin 간의 의존 관계를 보도록 하자.


이전에 만들었던 HelloWorldOSGi의 Plugin에 HelloOSGiWorldPrinter.java를 추가하고

HelloWoldOSGiSub Plugin을 추가로 만들어서 HelloOSGiWorldPrinter에 정의된 메소드를 호출해보도록 하겠다.



추가 프로젝트 생성

1. HelloWorldOSGi Project에 다른 Plugin에서 호출할 HelloOSGiWorldPtinter.java를 생성한다.

     그리고 printer method를 추가한다.

더보기


2. 위에서 만든 HelloOSGiWorldPrinter.java를 호출할 다른 Plugin 프로젝트 HelloWorldOSGiSub을 생성한다.

    Activator 이름은 HelloWorldOSGi 프로젝트와 구분하기위해 SubActivator로 바꾸었다.


     다음은 프로젝트가 생성된 모습이다. 



HelloWorldOSGi 프로젝트의 class 참조하기

1. SubActivator.java의 start method에 HelloWorldOSGi 프로젝트의 HelloOSGiWorldPrinter 를 생성해보면 다음과 같이 에러가 난다. 

    당연하겠지만 참조를 못하는 것이다.

더보기


2. HelloWorldOSGi 의 MANIFAST.MF에 

    Export-Package: kr.co.jabsiri.helloworldosgi 를 추가 한다. ( 다음 한줄을 비워 두는 것을 잊지 말자 )

더보기


3. HelloWorldOSGiSub 프로젝트의  MANIFAST.MF를 열고 

    Import-Package에 kr.co.jabsiri.helloworldosgi 를 추가한다. ( 다음 한줄을 비워 두는 것을 잊지 말자 )

더보기




4. 다음 화면 처럼 syntax error가 사라졌다

더보기



배포 및 install

1. 프로젝트에서 마우스 오른쪽 버튼 클릭 후 Export에서 Deployable plug-ins and fragments를 선택하고 배포할 plugin을 체크한후 배포한다.

2. ss 명령어로 현재 설치되어 있는 plugin을 확인 후 

    install file:sample.HelloWorldOSGiSub_1.0.0.jar를 입력하여 plugin을 설치한다.

osgi> ss

"Framework is launched."



id      State       Bundle

0       ACTIVE      org.eclipse.osgi_3.10.0.v20140606-1445

1       ACTIVE      org.eclipse.equinox.common_3.6.200.v20130402-1505

2       ACTIVE      org.eclipse.equinox.console_1.1.0.v20140131-1639

3       ACTIVE      org.apache.felix.gogo.shell_0.10.0.v201212101605

4       ACTIVE      org.apache.felix.gogo.command_0.10.0.v201209301215

5       ACTIVE      org.apache.felix.gogo.runtime_0.10.0.v201209301036

6       RESOLVED    sample.HelloWorldOSGi_1.0.0


osgi> install file:sample.HelloWorldOSGiSub_1.0.0.jar

Bundle id is 7

Location             file:sample.HelloWorldOSGiSub_1.0.0.jar

State                2

Bundle                   7|Installed  |    1|sample.HelloWorldOSGiSub (1.0.0)

Version              1.0.0

LastModified         1408530147306

Headers               Bundle-Activator = kr.co.jabsiri.helloworldosgisub.SubActi

vator

 Bundle-ManifestVersion = 2

 Bundle-Name = HelloWorldOSGiSub

 Bundle-RequiredExecutionEnvironment = JavaSE-1.6

 Bundle-SymbolicName = sample.HelloWorldOSGiSub

 Bundle-Version = 1.0.0

 Import-Package = org.osgi.framework;version="1.3.0",kr.co.jabsiri.helloworldosg

i

 Manifest-Version = 1.0



BundleContext        null

BundleId             7

SymbolicName         sample.HelloWorldOSGiSub

RegisteredServices   null

ServicesInUse        null

Module               osgi.identity; osgi.identity="sample.HelloWorldOSGiSub"; ty

pe="osgi.bundle"; version:Version="1.0.0" [id=7]


osgi> 



3. ss 명령어로 설치된 plugin을 확인 해보자

osgi> ss

"Framework is launched."



id      State       Bundle

0       ACTIVE      org.eclipse.osgi_3.10.0.v20140606-1445

1       ACTIVE      org.eclipse.equinox.common_3.6.200.v20130402-1505

2       ACTIVE      org.eclipse.equinox.console_1.1.0.v20140131-1639

3       ACTIVE      org.apache.felix.gogo.shell_0.10.0.v201212101605

4       ACTIVE      org.apache.felix.gogo.command_0.10.0.v201209301215

5       ACTIVE      org.apache.felix.gogo.runtime_0.10.0.v201209301036

6       RESOLVED    sample.HelloWorldOSGi_1.0.0

7       INSTALLED   sample.HelloWorldOSGiSub_1.0.0

osgi> 



Plugin 의존도 확인 

1. sample.HelloWorldOSGi 가 start 상태가 아닐 때 (위에서는 stop 시켜서 RESOLVED 상태임 ) sample.HelloWorldOSGiSub을 start 시켜보자.

    아래 처럼 Exception이 발생 한다.

osgi> start 7

gogo: BundleException: Could not resolve module: sample.HelloWorldOSGiSub [7]

  Unresolved requirement: Import-Package: kr.co.jabsiri.helloworldosgi


osgi> 


2. sample.HelloWorldOSGi 는 새로 배포 되었으므로 update를 하고 

    다시 sample.HelloWorldOSGiSub을 start 시켜보자.    

osgi> update 6

osgi> ss

"Framework is launched."



id      State       Bundle

0       ACTIVE      org.eclipse.osgi_3.10.0.v20140606-1445

1       ACTIVE      org.eclipse.equinox.common_3.6.200.v20130402-1505

2       ACTIVE      org.eclipse.equinox.console_1.1.0.v20140131-1639

3       ACTIVE      org.apache.felix.gogo.shell_0.10.0.v201212101605

4       ACTIVE      org.apache.felix.gogo.command_0.10.0.v201209301215

5       ACTIVE      org.apache.felix.gogo.runtime_0.10.0.v201209301036

6       INSTALLED   sample.HelloWorldOSGi_1.0.0

7       INSTALLED   sample.HelloWorldOSGiSub_1.0.0

osgi> start 6

start hello osgi world

osgi> ss

"Framework is launched."



id      State       Bundle

0       ACTIVE      org.eclipse.osgi_3.10.0.v20140606-1445

1       ACTIVE      org.eclipse.equinox.common_3.6.200.v20130402-1505

2       ACTIVE      org.eclipse.equinox.console_1.1.0.v20140131-1639

3       ACTIVE      org.apache.felix.gogo.shell_0.10.0.v201212101605

4       ACTIVE      org.apache.felix.gogo.command_0.10.0.v201209301215

5       ACTIVE      org.apache.felix.gogo.runtime_0.10.0.v201209301036

6       ACTIVE      sample.HelloWorldOSGi_1.0.0

7       ACTIVE      sample.HelloWorldOSGiSub_1.0.0

osgi> stop 7

osgi> start 7


위와같이 start, stop을 반복해도 Exception이 발생 하지 않는다.

( ** 그런데 6번을 start시켰을때 7번이 같이 install start 될줄은 몰랐다. 관련된 것이 있으면 같이 start 되나보다.. start를 따로 해야할줄 알았는데...)


확실하게 눈으로 확인...

1. 눈으로 정확히 확인을 해보기 위해 SubActivator start, stop method에 다음과 같이 printer.printer("")를 추가하였다.

더보기


2. 재 배포후 다음처럼 명령어를 입력해보자

osgi> update 7

print string : I am sub activator !!!

osgi> stop 7

print string : Bye Bye !!!

osgi>


HelloWorldOSGi plugin에 있는 HelloOSGiWorldPrinter.printer method가 호출된 것을 확인 할 수 있다.




첨부 1 : HelloWorldOSGi plugin Eclipse Project

HelloWorldOSGi_3.zip



첨부 2 : OSGi Framework

plugins_osgi_3.zip



참고 자료


[1] Guru's Blog

OSGi 시작하기 

http://xguru.net/page/2?s=osgi 





'JAVA' 카테고리의 다른 글

[ OSGi ] 6 - Spring DM 3  (0) 2014.08.28
[ OSGi ] 5 - Spring DM 2  (0) 2014.08.26
[ OSGi ] 4 - Spring DM 1  (0) 2014.08.25
[ OSGi ] 3 - OSGi plugin 의존 관계  (0) 2014.08.20
[ OSGi ] 2 - OSGi plugin project  (2) 2014.08.19
[ OSGi ] 1 - OSGi 기초  (0) 2014.06.24
Posted by jabsiri
TAG Equinox, OSGi




[ OSGi ] 1 - OSGi 기초 에서 OSGi platform 까지 구동했다.


여기서는 OSGi안에서 서비스될 plugin( bundle ) 을 만들어 보도록 하자.

우선 eclipse를 구동후 프로젝트를 생성하자


프로젝트 생성 

1. 프로젝트 생성에서 Plug-in Project를 선택한다.





2. This plug-in is targeted to run with 에서 "an OSGi framework" 을 선택하고 "standrd"를 선택한다.




3. ID를 입력한다. 

  ID : plugin(bundle)의 식별자가 된다. (OSGi command 에서 ss 명령어 입력시 나오는  Bundle-SymbolicName ) 

  Version : plugin(bundle) 버전

  Name : Bundle-Name

  Activator : plugin 시작시 실행되는 java class





MANIFEST.MF 확인 

프로젝트 생성시 입력한 정보들이 MANIFEST.MF에 반영이 되었는지 확인한다.

참고로 MANIFEST.MF 제일 마직막줄에는 밑에 빨간 박스처럼 한줄이 추가로 들어가야 bug 없이 잘 동작 한다. 


 

더보기




Activator.java 확인 

자동으로 생성된 Activator.java의 start method에 System.out.println("start hello osgi world");

 stop method에 System.out.println("stop hello osgi world");를 입력 한다.

더보기


Plugin 배포

1. 프로젝트에서 오른쪽 마우스 클릭후 Export...를 선택한다.

 


2. Deployable plug-ins and fragments를 선택한다.



3. 배포할 경로를 선택한다.

   아래와 같이 sample을 선택하면 sample/plugins 밑으로 자동으로 들어간다. 


4. 최종적으로 폴더는 다음과 같은 구조로 된다.

sample 

   |-- plugins

            |-- org.apache.felix.gogo.command_xxx.jar

            |-- org.apache.felix.gogo.runtime_xxx.jar

            |-- org.apache.felix.gogo.shell_xxx.jar

            |-- org.eclipse.equinox.common_xxx.jar

            |-- org.eclipse.equinox.console_xxx.jar

            |-- org.eclipse.osgi_xxx.jar

         |-- sample.HelloWorldOSGi_1.0.0.jar

   |-- configuration

            |-- config.ini




Plug-in Install

1. OSGi를 실행 시킨다.

C:\develop\OSGi\sample\plugins>java -Declipse.ignoreApp=true -jar org.eclipse.osgi_3.10.0.v20140606-1445.jar -console -consoleLog 

osgi>





2. ss 명령어를 입력하면 다음과 같이 나온다

osgi> ss

"Framework is launched."



id      State       Bundle

0       ACTIVE      org.eclipse.osgi_3.10.0.v20140606-1445

1       ACTIVE      org.eclipse.equinox.common_3.6.200.v20130402-1505

2       ACTIVE      org.eclipse.equinox.console_1.1.0.v20140131-1639

3       ACTIVE      org.apache.felix.gogo.shell_0.10.0.v201212101605

4       ACTIVE      org.apache.felix.gogo.command_0.10.0.v201209301215

5       ACTIVE      org.apache.felix.gogo.runtime_0.10.0.v201209301036

osgi>


3. plug-in install 명령어를 입력한 후 ss 명령어를 다시 입력하면

sample.HelloWorldOSGi.jar가 install 된 것을 확인 할수 있다.

osgi> install file:sample.HelloWorldOSGi_1.0.0.jar


Bundle id is 6

Location             file:sample.HelloWorldOSGi_1.0.0.jar

State                2

Bundle                   6|Installed  |    1|sample.HelloWorldOSGi (1.0.0)

Version              1.0.0

LastModified         1408447306585

Headers               Bundle-Activator = kr.co.jabsiri.helloworldosgi.Activator

 Bundle-ManifestVersion = 2

 Bundle-Name = HelloWorldOSGi

 Bundle-RequiredExecutionEnvironment = JavaSE-1.6

 Bundle-SymbolicName = sample.HelloWorldOSGi

 Bundle-Version = 1.0.0

 Import-Package = org.osgi.framework;version="1.3.0"

 Manifest-Version = 1.0



BundleContext        null

BundleId             6

SymbolicName         sample.HelloWorldOSGi

RegisteredServices   null

ServicesInUse        null

Module               osgi.identity; osgi.identity="sample.HelloWorldOSGi"; type=

"osgi.bundle"; version:Version="1.0.0" [id=6]


osgi> ss

"Framework is launched."



id      State       Bundle

0       ACTIVE      org.eclipse.osgi_3.10.0.v20140606-1445

1       ACTIVE      org.eclipse.equinox.common_3.6.200.v20130402-1505

2       ACTIVE      org.eclipse.equinox.console_1.1.0.v20140131-1639

3       ACTIVE      org.apache.felix.gogo.shell_0.10.0.v201212101605

4       ACTIVE      org.apache.felix.gogo.command_0.10.0.v201209301215

5       ACTIVE      org.apache.felix.gogo.runtime_0.10.0.v201209301036

6       INSTALLED   sample.HelloWorldOSGi_1.0.0

osgi> 

** plugins folder 밑의 파일은 full path를 입력하지 않지만, plugins folder 외부에 있는 파일은 full path를 입력해준다. 

( 예: install file:C:\sample.HelloWorldOSGi_1.0.0.jar )


4. plugin을 start 시키기 위해 start 명령어를 입력한다.

osgi> start 6

start hello osgi world

osgi> ss

"Framework is launched."



id      State       Bundle

0       ACTIVE      org.eclipse.osgi_3.10.0.v20140606-1445

1       ACTIVE      org.eclipse.equinox.common_3.6.200.v20130402-1505

2       ACTIVE      org.eclipse.equinox.console_1.1.0.v20140131-1639

3       ACTIVE      org.apache.felix.gogo.shell_0.10.0.v201212101605

4       ACTIVE      org.apache.felix.gogo.command_0.10.0.v201209301215

5       ACTIVE      org.apache.felix.gogo.runtime_0.10.0.v201209301036

6       ACTIVE      sample.HelloWorldOSGi_1.0.0

start 되면서 Activator.java의 start method에 입력한 "start hello osgi world" 출력된 것을 확인 할 수 있다.

ss 명령어 입력시 State도 "ACTIVE"로 변경된 것을 볼수 있다.


4. plugin을 stop 시키기 위해 stop 명령어를 입력한다.

osgi> stop 6

stop hello osgi world

osgi> ss

"Framework is launched."



id      State       Bundle

0       ACTIVE      org.eclipse.osgi_3.10.0.v20140606-1445

1       ACTIVE      org.eclipse.equinox.common_3.6.200.v20130402-1505

2       ACTIVE      org.eclipse.equinox.console_1.1.0.v20140131-1639

3       ACTIVE      org.apache.felix.gogo.shell_0.10.0.v201212101605

4       ACTIVE      org.apache.felix.gogo.command_0.10.0.v201209301215

5       ACTIVE      org.apache.felix.gogo.runtime_0.10.0.v201209301036

6       RESOLVED    sample.HelloWorldOSGi_1.0.0

osgi>

stop 되면서 Activator.java의 stop method에 입력한 "stop hello osgi world" 출력된 것을 확인 할 수 있다.

ss 명령어 입력시 State도 "RESOLVED"로 변경된 것을 볼수 있다.





첨부 1 : HelloWorldOSGi plugin Eclipse Project 

HelloWorldOSGi_2.zip



첨부 2 : OSGi Framework

plugins_osgi_2.zip



참고 자료


[1] Guru's Blog

OSGi 시작하기 

http://xguru.net/page/2?s=osgi 






'JAVA' 카테고리의 다른 글

[ OSGi ] 6 - Spring DM 3  (0) 2014.08.28
[ OSGi ] 5 - Spring DM 2  (0) 2014.08.26
[ OSGi ] 4 - Spring DM 1  (0) 2014.08.25
[ OSGi ] 3 - OSGi plugin 의존 관계  (0) 2014.08.20
[ OSGi ] 2 - OSGi plugin project  (2) 2014.08.19
[ OSGi ] 1 - OSGi 기초  (0) 2014.06.24
Posted by jabsiri
TAG Equinox, OSGi

[ OSGi ] 1 - OSGi 기초

JAVA 2014.06.24 22:47




OSGi란 ( Open Service Gateway initiative )

OSGi는 Java VM에서  구동 될수 있는 플렛폼의 규약(Dynamic Module for Java)으로 Bundle( 혹은 Component / Plug-in / Moudule )의 Life Cycle ( install, start, stop, update, uninstall )을 Application의 재시작 없이 관리하는 프레임워크이다.

OSGi의 적용된 대표적인 Application으로는 java 개발자라면 누구나 사용하는 Eclipse가 있다. (Eclipse의 Plugin인은 OSGi 기반이다. )


OSGi는 Specification만 존재하므로 여러 구현체 들이 따로 있는데 다음과 같다.

  • Eclipse Equinox
  • Apache Felix
  • Knopflerfish
  • Concierge
  • Posyst mBedded Server


OSGi 시작

OSGi를 시작하기 위해서는 위에서 나열한 구현체들중 하나가 필요한데 여기서는 Eclipse의 Equinox를 사용하기로 한다. 

Eclipse 설치 된 곳의  plugin folder에 들어가면 "org.eclipse.osgi_3.8.1.v20120830-144521.jar"와 같은 ( 버전별로 파일 명은 다를 수 있음 ) jar파일이 있는데 이 파일을 이용한다. 아니면 http://download.eclipse.org/equinox/ 에서 Eclipse 버전별 equinox를 받을 수 있다.


나는 실행의 편의성을 위해 equinox.jar라고 이름을 변경하여 사용한다.


OSGi의 실행을 위해 command 창에서 "java -Dosgi.console.enable.builtin=true -jar equinox.jar -console" 명령어를 입력한다. 

java -Dosgi.console.enable.builtin=true -jar equinox.jar -console


osgi> 



*** 추가내용 *********************************************************************************************

equinox osgi 3.8 버전 이후 부터 console이 바뀌었다고한다. 


3.8 버전 이하는 위에서 처럼 하면되고

3.8 버전 이상에서는 다음과 같이 해야한다. 


1. 폴더구조

sample 

   |-- plugins

            |-- org.apache.felix.gogo.command_xxx.jar

            |-- org.apache.felix.gogo.runtime_xxx.jar

            |-- org.apache.felix.gogo.shell_xxx.jar

            |-- org.eclipse.equinox.common_xxx.jar

            |-- org.eclipse.equinox.console_xxx.jar

            |-- org.eclipse.osgi_xxx.jar

   |-- configuration

            |-- config.ini


2. config.ini 파일 ( osgi 구동시 같이 start 될 bundle 목록 )

#Eclipse Runtime Configuration File

osgi.bundles=org.eclipse.equinox.common_3.6.200.v20130402-1505.jar@2:start,\

org.eclipse.equinox.console_xxx.jar@start,\

org.apache.felix.gogo.shell_xxx.jar@start,\

org.apache.felix.gogo.command_xxx.jar@start,\

org.apache.felix.gogo.runtime_xxx.jar@start

osgi.bundles.defaultStartLevel=4


3. 실행

plugins 폴더 밑에서 

 java -Dosgi.console.enable.builtin=true -jar org.eclipse.osgi_xxx.jar -console

와 같이 입력하면 된다.


**********************************************************************************************************


osgi command가 실행 되면 "ss"를 입력해보자


osgi> ss


Framework is launched.


id State       Bundle

0 ACTIVE      org.eclipse.osgi_3.9.1.v20140110-1610


osgi> 


osgi의 command line 명령어는 "help"를 입력하거나 다음 URL을 참고.

http://eclipse.org/equinox/documents/quickstart-framework.php

http://isurues.wordpress.com/2009/01/01/useful-equinox-osgi-commands/



첨부 : OSGi Framework

plugins_osgi_1.zip




참고 자료


[1] Guru's Blog

OSGi 시작하기 

http://xguru.net/443 




참고로 OSGi의 자료는 대부분 2007-8 년도의 문서들이 많다. 한국이건 외국이건...

저 시기때 한창 많은 글들이 올라오던 기술을 이제서야 접해 봤다는 것이....


'JAVA' 카테고리의 다른 글

[ OSGi ] 6 - Spring DM 3  (0) 2014.08.28
[ OSGi ] 5 - Spring DM 2  (0) 2014.08.26
[ OSGi ] 4 - Spring DM 1  (0) 2014.08.25
[ OSGi ] 3 - OSGi plugin 의존 관계  (0) 2014.08.20
[ OSGi ] 2 - OSGi plugin project  (2) 2014.08.19
[ OSGi ] 1 - OSGi 기초  (0) 2014.06.24
Posted by jabsiri
TAG Equinox, OSGi