이제서야 OSGi 에 관심이 생겨서 뭔가를 만들어보기 위해서 OSGi + Tomcat 6 + SpringDM 1 개발 환경을 구성해 봅니다.
Eclipse Indigo + Maven Integration for Eclipse
Create Project
File - New - Other... → Maven - Maven Project
[maven-archetype-quickstart] 선택합니다.
[Group Id], [Artifact Id] 아무거나 입력 합니다. -_-;;
[Package] 는 필요가 없습니다.
Create Target Definition
File - New - Other... → Plug-in Development - Target Definition
[Parent Folder]는 전에 만든 "spring-dm-platform" 프로젝트를 선택합니다.
File name: spring-dm-tomcat.target
Initalize the target definition with: Nothing
lib 폴더를 하나 생성합니다.
target 폴더는 메이븐 라이브러리가 복사되는 곳이고, lib 폴더는 메이븐으로 구하지 못한 라이브러를 넣어둘 것입니다.
spring-dm-tomcat.target 파일을 열어 편집합니다.
Target: SpringDM with Tomcat
오른쪽 Add... 버튼을 클릭해서 Locations 을 추가합니다.
Directory 선택
Variables.. 를 이용해서 현재 프로젝트 경로(project_loc)를 얻어내고 하위 폴더 target 을 입력합니다. (그냥 입력해도 됨..)
같은 방법으로 lib 폴더도 선택합니다.
파일 저장 후 Windows - Preferences - Plug-in Development - Target Platform
SpringDM with Tomcat 을 선택합니다.
Running OSGi Framework
이제 한번 실행시켜 봅시다.
Run - Run Configurations...
왼쪽 메뉴 중에 OSGi Framework 에서 오른쪽 버튼 클릭 - New
이름 적당히 지어 주시고 Run 을 클릭해 봅시다.
org.eclipse.osgi 플러그인이 없다고 에러가 납니다.
Setting Osgi Framework on Maven
이제 메이븐으로 OSGi Framework 라이브러리를 세팅합시다.
pom.xml 파일을 열어 아래와 같이 수정 합니다.
메이븐에 대해서 설명하지는 않겠습니다. -_-;;
위의 라이브러리 저장소(repository)는 SpringSource Repository(FAQ)에서 확인할 수 있습니다.
이제 SpringSource Repository에서 번들(라이브러리)를 하나씩 찾아서 넣어야 합니다. ㅠ_ㅠ;;
검색하는 방법은 [Advanced Search]나 오른쪽 상단 [Quick Search] 을 이용해서 검색하면 됩니다.
일단 OSGi Framework 실행 했을 때 없다고한 플러그인 라이브러리를 검색해봅시다.
검색해서 나온 버전 중 가장 최신 버전을 선택합니다.
중간에 보면 Maven 부분이 있습니다. 이걸 복사해서 <dependencies> </dependencies> 사이에 붙여넣기 하면 됩니다. ㅎㅎ
<dependencies>
<!-- 라이브러리 설정 -->
<dependency>
<groupId>org.eclipse.osgi</groupId>
<artifactId>org.eclipse.osgi</artifactId>
<version>3.7.1.R37x_v20110808-1106</version>
</dependency>
</dependencies>
저장 후 pom.xml 파일에서 오른쪽버튼 클릭 후 Run As - Maven install 클릭 합니다.
그러면 target 폴더에 jar 파일이 복사가 됩니다.
이제 spring-dm-tomcat.target 파일을 열어봅시다.
아래와 같이 번들이 추가 되어있습니다.
※ 메이븐을 이용해서 빠르게 라이브러리를 바꿔치기 하다보면 번들(라이브러리)이 갱신이 안될 때가 있는데 그냥 파일 닫았다가 다시 열어주면 갱신이 되더군요....
맨위의 타이틀 오른쪽에 "Set as Target Platform"을 클릭해야 실제 적용이 됩니다. 주의!
이제 다시 Run Configurations 로 가봅시다. 추가한 번들이 올라와 있습니다. 선택 후 Run!
콘솔 창을 보면 OSGi Framework 가 실행되었습니다. ㅠ_ㅠ
이제 OSGi 할 준비가 된 것입니다. ㅋㅋ
톰켓이나 웹로직 같이 끄려면 빨간 버튼(Terminate)을 이용해서 끄면 됩니다.
나중에 톰켓를 띄우게 될텐데 OSGi Framework 한번 실행한 상태에서 한번 실행하면 톰켓 포트 충돌로 인한 에러를 볼 수 있습니다.
Setting SpringDM on Maven
바로 SpringDM을 적용해 봅시다!!
SpringSource Repository 에서 "spring", "spring-osgi", "slf4j" 를 검색해서 최신 버전을 적용 합니다.
이제 pom.xml 에서 마우스 오른쪽 버튼 - Run As - Maven install 해서 jar 파일을 target 에 생기게 합니다.
그리고 spring-dm-tomcat.target 파일을 열어서 ${project_loc}/target 폴더에 플러그인 갯수가 늘어났는지 확인합니다.
※ 만약 파일은 존재하는데 변경이 되지 안았다면 spring-dm-tomcat.target 파일 닫고 바로 다시 열어주면 카운트가 변경 되어 있을 겁니다.
상단 오른쪽의 "Set as Target Platform" 링크를 클릭하여 라이브러리를 적용시켜 줍니다.
Run Configurations 창으로 가서 추가된 번들(또는 라이브러리)를 선택합니다.
그 후 오른쪽 아래 "Validate Bundles" 버튼을 클릭합니다. 버튼명 그대로 번들들의 유효성을 검사하게 됩니다.
아래와 같이 어떤 라이브러리에서 필요한 라이브러리가 빠져있는지 나옵니다.
웹에 관련된 부분은 바로 이어서 할 것이므로 일단 이 번들은 빼고 구동(Run)합니다.
아래와 같이 나오면 성공! 웹쪽을 뺀 SpringDM 까지 올라갔습니다.
osgi> log4j:WARN No appenders could be found for logger (org.springframework.osgi.extender.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.7.1.R37x_v20110808-1106
1 ACTIVE org.springframework.transaction_3.2.1.RELEASE
2 ACTIVE org.springframework.osgi.core_1.2.1
3 ACTIVE org.springframework.osgi.extensions.annotations_1.2.1
4 ACTIVE com.springsource.org.apache.log4j_1.2.16
5 ACTIVE org.springframework.jdbc_3.2.1.RELEASE
6 ACTIVE org.springframework.oxm_3.2.1.RELEASE
7 ACTIVE org.springframework.aspects_3.2.1.RELEASE
8 ACTIVE com.springsource.org.apache.commons.logging_1.1.1
9 ACTIVE org.springframework.context.support_3.2.1.RELEASE
10 ACTIVE org.springframework.core_3.2.1.RELEASE
11 ACTIVE org.springframework.beans_3.2.1.RELEASE
12 ACTIVE org.springframework.context_3.2.1.RELEASE
13 ACTIVE org.springframework.aop_3.2.1.RELEASE
14 RESOLVED com.springsource.slf4j.log4j_1.6.1
Master=17
15 ACTIVE org.springframework.expression_3.2.1.RELEASE
16 ACTIVE org.springframework.orm_3.2.1.RELEASE
17 ACTIVE com.springsource.slf4j.api_1.6.1
Fragments=14
18 ACTIVE com.springsource.org.aopalliance_1.0.0
19 ACTIVE org.springframework.osgi.extender_1.2.1
20 ACTIVE org.springframework.osgi.io_1.2.1
osgi>
Configuration Log4j
OSGi Framework 를 실행 하면 아래와 같은 경고가 나오게 되는데 흔하디 흔한 log4j.properties / log4j.xml 파일 못 찾는 경고입니다.
log4j:WARN No appenders could be found for logger (org.springframework.osgi.extender.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.
첨부한 log4j.xml 파일을 프로젝트 폴더에 복사합니다.
Run Configurations 창의 Arguments 탭으로 이동합니다.
VM arguments 부분에 -Dlog4j.debug=true -Dlog4j.configuration=file:log4j.xml 를 추가합니다.
Working directory 부분은 현재 자기의 프로젝트 경로로 바꿔줍니다.
Workspace... 버튼 클릭 후 spring-dm-platform 프로젝트 폴더를 선택하면 됩니다.
이제 OSGi Framework 를 실행하면 로그가 출력 됩니다.
osgi> log4j: Using URL [file:log4j.xml] for automatic log4j configuration.
log4j: Preferred configurator class: org.apache.log4j.xml.DOMConfigurator
log4j: System property is :null
log4j: Standard DocumentBuilderFactory search succeded.
log4j: DocumentBuilderFactory is: com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl
log4j: debug attribute= "null".
log4j: Ignoring debug attribute.
log4j: reset attribute= "false".
log4j: Threshold ="null".
log4j: Retreiving an instance of org.apache.log4j.Logger.
log4j: Setting [org.springframework.osgi.web.tomcat.internal] additivity to [false].
log4j: Level value for org.springframework.osgi.web.tomcat.internal is [debug].
log4j: org.springframework.osgi.web.tomcat.internal level set to DEBUG
log4j: Class name: [org.apache.log4j.ConsoleAppender]
log4j: Parsing layout of class: "org.apache.log4j.PatternLayout"
log4j: Setting property [conversionPattern] to [%d _ %t _ %p _ %c _ %m%n].
log4j: Adding appender named [console] to category [org.springframework.osgi.web.tomcat.internal].
log4j: Retreiving an instance of org.apache.log4j.Logger.
log4j: Setting [org.springframework] additivity to [false].
log4j: Level value for org.springframework is [info].
log4j: org.springframework level set to INFO
log4j: Adding appender named [console] to category [org.springframework].
log4j: Level value for root is [warn].
log4j: root level set to WARN
log4j: Adding appender named [console] to category [root].
2013-03-27 00:54:43,505 _ Start Level Event Dispatcher _ INFO
_ org.springframework.osgi.extender.internal.activator.ContextLoaderListener
_ Starting [org.springframework.osgi.extender] bundle v.[1.2.1]
2013-03-27 00:54:43,545 _ Start Level Event Dispatcher _ INFO
_ org.springframework.osgi.extender.internal.support.ExtenderConfiguration
_ No custom extender configuration detected; using defaults...
2013-03-27 00:54:43,550 _ Start Level Event Dispatcher _ INFO
_ org.springframework.scheduling.timer.TimerTaskExecutor _ Initializing Timer
osgi>
여기까지 했으면 이제 웹을 제외한 SpringDM을 사용할 준비가 되었습니다.
Setting Web Platform
이제 거의 다 왔습니다.... 후우~.. 이제 웹도 되게 합시다!
Run Configurations 창에서 전 단계에서 선택하지 않았던 4개의 웹 관련 번들을 선택 후 검사합니다. (Validate Bundles 버튼)
아래에 나온 없는 패키지가 포함된 번들을 찾아줘야 합니다.
일단 서블릿 2.4 버전을 찾아서 넣어줍시다.
이렇게 추가된 라이브러리를 적용한 후 다시 Run Configurations 창을 엽니다.
Add Required Bundles 버튼을 클릭하면 필요한 라이브러리를 자동으로 선택 해줍니다. (만약 있다면..)
이제 번들 유효성 검사를 해보면 아무 이상이 없다고 합니다.
실행! 잘 되는듯 하다가 에러가 나는군요...
2013-03-28 23:20:49,878 _ WebExtender-Init _ INFO
_ org.springframework.osgi.web.extender.internal.activator.WarListenerConfiguration
_ No custom extender configuration detected; using defaults...
Exception in thread "WebExtender-Init" java.lang.NoClassDefFoundError: org/apache/catalina/Loader
at o.s.osgi.web.extender.internal.activator.WarListenerConfiguration.createDefaultWarDeployer(WarListenerConfiguration.java:194)
at org.springframework.osgi.web.extender.internal.activator.WarListenerConfiguration.<init>(WarListenerConfiguration.java:105)
at org.springframework.osgi.web.extender.internal.activator.WarLoaderListener$1.run(WarLoaderListener.java:361)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ClassNotFoundException: org.apache.catalina.Loader
at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:513)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:429)
at org.eclipse.osgi.internal.loader.BundleLoader.findClass(BundleLoader.java:417)
at org.eclipse.osgi.internal.baseadaptor.DefaultClassLoader.loadClass(DefaultClassLoader.java:107)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 4 more
톰켓 번들을 설치합시다.
내용이 너무 길어저 pom.xml 만 남깁니다.
번들(라이브러리) 적용 후 우효성 검사를 하면 이상이 없다고 합니다.
보면 서블릿 번들이이 2.4/2.5 두개가 있는데 이중에 한가지만 선택하면 되겠습니다.
이제 실행해 봅시다.
WebExtender-Init _ ERROR _ o.s.osgi.web.deployer.tomcat.TomcatWarDeployer _ No Catalina Service found, bailing out
o.s.osgi.service.ServiceUnavailableException: service matching filter=[(objectClass=org.apache.catalina.Service)] unavailable
WebExtender-Init _ ERROR _ o.s.osgi.web.extender.internal.activator.WarLoaderListener _ Cannot property start Spring DM WebExtender; stopping bundle...
o.s.osgi.OsgiException: Cannot create Tomcat deployer
Caused by: o.s.osgi.service.ServiceUnavailableException: service matching filter=[(objectClass=org.apache.catalina.Service)] unavailable
WebExtender-Init _ INFO _ org.springframework.scheduling.timer.TimerTaskExecutor _ Cancelling Timer
org.apache.catalina.Service 서비스를 찾을 수 없다. 즉 톰켓이 안 떠있다는 겁니다.
catalina.start.osgi-6.0.16-20080327.121306-4.jar
첨부한 번들을 lib 폴더에 복사해주고 적용 시킵니다. (이건 메이븐에 없더군요...)
마지막으로 실행!
Tomcat Catalina Start Thread _ INFO _ o.s.osgi.web.tomcat.internal.Activator _ Starting Apache Tomcat/6.0.32 ...
Tomcat Catalina Start Thread _ DEBUG _ o.s.osgi.web.tomcat.internal.Activator _ Reading default server configuration from bundleresource://45.fwk1110027070/conf/embedded-server-defaults.properties
2013. 3. 28 오후 11:40:53 org.apache.catalina.startup.Embedded start
정보: Starting tomcat server
2013. 3. 28 오후 11:40:53 org.apache.catalina.core.StandardEngine start
정보: Starting Servlet Engine: Apache Tomcat/6.0.32
2013. 3. 28 오후 11:40:53 org.apache.coyote.http11.Http11Protocol init
정보: Initializing Coyote HTTP/1.1 on http-127.0.0.1-8080
2013. 3. 28 오후 11:40:53 org.apache.coyote.http11.Http11Protocol start
정보: Starting Coyote HTTP/1.1 on http-127.0.0.1-8080
Tomcat Catalina Start Thread _ INFO _ o.s.osgi.web.tomcat.internal.Activator _ Succesfully started Apache Tomcat/6.0.32
WebExtender-Init _ INFO _ o.s.osgi.service.importer.support.OsgiServiceProxyFactoryBean _ Found mandatory OSGi service for bean []
Tomcat Catalina Start Thread _ INFO _ o.s.osgi.web.tomcat.internal.Activator _ Published Apache Tomcat/6.0.32 as an OSGi service
WebExtender-Init _ INFO _ o.s.osgi.web.deployer.tomcat.TomcatWarDeployer _ Found service Catalina
후우... 성공!
마지막으로 첨부한 web.xml 파일을 conf/web.xml 에 복사합니다. (그냥 톰켓에 있는 web.xml 입니다)
이 파일이 있어야 나중에 웹어플 배치했을 때 정상적으로 됩니다.
안그러면 배치했을 때 아래 로그와 함께 영원히 404를 볼 수 있습니다.
[ INFO - WebExtender-Init] org.springframework.osgi.web.extender.internal.activator.WarLoaderListener - hello.web (hello.web) is a WAR, scheduling war deployment on context path [/hello.web] (web.xml found at [bundleentry://11.fwk854535264/WEB-INF/web.xml])
2013. 3. 30 오전 2:03:35 org.apache.catalina.startup.ContextConfig defaultWebConfig
정보: No default web.xml
[ INFO - Timer-0] org.springframework.osgi.web.deployer.tomcat.TomcatWarDeployer - Successfully deployed bundle [hello.web (hello.web)] at [/hello.web] on server org.apache.catalina.startup.Embedded/1.0
Trouble Shooting
설정을 바꿨는데도 안바뀐다면?
Run Configurations 의 Settings 탭에서 "Clear the configuration area before launching"를 체크해주세요.
중간 중간 아래와 같은 에러가 난다면? 하라는 대로 하면 됩니다. -_-;;
마지막으로 최종 pom.xml 파일 첨부합니다.
- 구) Spring OSGi / 신) Spring Dynamic Modules [본문으로]
'Framework > Spring OSGi' 카테고리의 다른 글
SpringDM Test Project - hello.osgi (0) | 2013.04.07 |
---|