S1A – Spring Dynamic Modules Updates : Costin Leau

스프링 DM 기본 설명

스프링 애플리케이션에서 추가 코드 없이 OSGi를 사용할 수 있다.
=> 스프링 철학과 일맥상통한다. non-invasive

스프링 DM
– 오라클(/BEA)와 함꼐 협업하고 있다.
=> 스프링 DM이 OSGi 스펙을 주도 하고 있다.

Raw OSGi
=> 다이나믹스를 다루기 위한 반복적인 코드가 필요하다.
=> OSGi 번들은 일반 JAR 파일로 무엇을 사용하고공개할지 정의한 파일을 가지고 있다.
=> 손수 해야 할 일이 많다.

OSGi에서 스프링 사용하기
=> OSGi 서비스를 룩업하지 말고 DI하기

POJO developement in OSGi

기능 살펴보기

번들 == ApplicationContext
=> 하나의 번들은 하나의 application context를 가지고 있다. 직접 만들 필요는 없다. 모듈을 정의하고 설정을 만들고 배포하면 되지.. 스프링을 이용하려고 뭔가를 하지 않아도 된다.

OSGi-aware Contexxt
=> OSGi 환경에 대해 알고 싶다면(예를 들어, BundleContextAware)같은 인터페이스를 사용할 수 있다.
=> bundle 스코프 제공
=> 여러 모듈에 걸친 application context 설정파일 사용가능

애플리케이션 == 모듈 집합

OSGi 서비스 == 스프링 빈

=> 서비스 레지스트리는 loose coupling을 실현해준다.

서비스 공개하기(export)
=> 보통 인터페이스를 기준으로 공개한다.
=>  auto-export 속성

서비스 참조하기(import)
=> 서비스 다이나믹스를 내부에서 다뤄준다.

데모
1. STS에서 dm 서버 실행한다.
2. localhost 2401로 telnet한다.
3. osgi> 콘솔 확인 help로 기본 명령어 확인
4. ss로 설치된 번들 확인
5. bundle 번들id로 번들 정보 확인

1. 간단한 서비스 공개(하나는 all-classses, 하는 interface)
2. 번들을 dm 서버에 설치하고 공개된 서비스 확인

1.  shape 번들 만들고 서비스 세 개 공개
2. MF 파일 고칠 거 없다.
3. dm 서버에 배포하고 공개된 서비스 확인

1. painter manager 번들 만들고 painter와 packageAdmin 서비스 레퍼런스 가져온다.
2. osgi:list로 여러 서비스를 참조할 수 있다.
3. BundleLogger에  packageAdmin 주입.

서비스 다이나믹(dynamics)
=> dynamic은 서비스가 언제든지 새로 추가되거나 없어질 수 있다는 거다.
Dependency resilience

만약
– 대응하는 서비스가 없다면
– 대응하는 서브시가 여러 개라면
– 대응하는 서비스가 사용 도중 없어지면
– 더 잘 매칭하는 새로운 서비스가 배포 되면

import cardinality
– 1..X: 애플리케이션 시작할 때 필요하다
=> X .. 1 일 때 서비스가 사라지면 다른 서비스 참조한다.
=> X .. N 일 때 서비스가 사라지면 컬렉션에서 빼준다.

데모

1. 쓰레드로 2초마다 그림그리는 메소드 실행하는 번들 만듬
2. painterManager 번들 stop
3. 다시 start
4. 로깅을 stop(등록한 서비스를 제거한다.)
=> 없어지면 대체제를 찾고 대체제가 없으면 기다린다.
5. 로깅 다시 start

리스닝
=> 메소드 매개 변수에서 서비스를 필터링할 수 있다.

통합 테스트 데모
1. AbsractConfigurableBundleCreatorTests 상속 받기
2. bundleContext.getBundles() 사용하기
3. getPlatformName으로 테스트할 플랫폼 선택가능. Platform.EQUINOX

1.2.0은 Compendium Services Integration
– Configuration Admin 속성을 참조하라.
– osgix 네임스페이스 공부할 것…

OSGi 4.2 계획
– Spring DM은 OSGi 4.2를 기준으로 한다.
RFC 124의 RI가 된다.
– 2009년 5/6월을 배포를 목표로..
=> 스프링 네임스페이스랑 OSGi 네임스페이스가 거의 비슷한 형태로..

로드맵
– 1.2.0은 2009년 1/2월
– 2.0(Spring, 3.0, JDK 5.0, RFC 124 RI) 2009년 5/6월

S1A – OSGi best practive by 코스틴 리우

자바 애플리케이션 모듈화는 어렵다. 하지만 해결책은 있다.

개요
– 모듈성 개요
– 클래스 & 리소스 로딩
– 서비스 다아나믹스

모듈화 목적
=> 차 사고 났을 때 헤드라이트 나가면 거기만 갈아 낄 수 있도록.
=>

모듈성이 없는 app
– web/facade/repository 한 덩어리

모듈성이 있는 app
– ADao, BDao, CService

OSGi
– 1999년부터 사용 가능
– JDK 1.2 호환

모듈화 대안 – JSR277/JAM
– JAva Module
– “Opaque” 스펙 진행중
=> 어떻게 되가고 있는지 모르겠다.
– JDK 7.0 호환
=> 왜냐면 새로운 키워드를 사용해야 해서…
– OSGi 호환

모듈화 대안 – HK2
=> glassfish 팀이 사용하고 있다.
– 2007년 말에 밸표됨
– 애노테이션 기반 간단 IoC
– 정적인 시스템

OSGi/JSR 277 비교
– http://www.osgi.org/blog/
– http://underlap.blogspot.com/

클래스로딩
– 모듈은 자기 내부 패키지와 다른 모듈에서 가져온 패키지만 로딩할 수 있다.
– 모든 패키지는 버전을 가지고 있다.

Type Leakage
  – 공개한 클래스 계층 구조에서 내부 클래스
  – 공개한 시그너쳐에 있는 내부 클래스
=> 이런 일이 발생하면 안 돼. 그럼 어떻게 해야 할까?
– 내부 패키지를 공개해(
– ‘연결’ 인터페이스를 축출해
– Generic public 타입을 사용해
– 검증 도구(bnd)를 사용해

추이적인 의존성
– A -> C1, B ->C2 => 이렇게 여러 버전 배포 가능하다. 이럴 때 X -> A, B 이렇게 되면.. C 패키지는 어떤 버전 사용하게 되는거야?? => A나 B가 사용하고 X가 직접 사용 안 하면 상관없겠지만 X가 직접 해당 패키지를 사용하게 되면 타입 캐스팅 충돌 발생할꺼다 그래서 바운더리를 만들어줘야 한다. X -> A, B, C1 이런식으로..
또는
=> A, B, X -> C2 이런식으로 한 버전을 참조하도록 한다.
– uses 지시어를 사용해서 둘 사이의 관계를 기술하라.

AOP
– 동적 클래스 확장
– 기존 모듈 경계를 깨트린다.
=> AOP의 아름다움은 바로 transparent하게  로깅이나 트랜잭션 등을 처리해 준다는 것이다.

(과거) 컴파일-타임 위빙
– Imports를 수정해야 한다.
– provisioning 을 통해서 한다.

로드 타임 위빙
=> 이미 리졸브 된 상태에서 추가로 필요한 패키지가 있으면 못 가져온다.
– Synthetic 클래스로더 하나가 Proxy Creator Module, Advoce Module, Target Module을 모두 관리해야 한다.

동적인 로드 타임 위빙
=> 위에서 설치한 모듈이 중간에 없어지면 어떡하냐.. 프록시를 없앴다가 다시 만들어야 돼.
– 의존하는 모듈을 update 해줘야 돼
=> SpringSource DM 서버에서는 알아서 해준다.

영속화/리모팅
– 클래스 로더 사용과 연관이 많다. => 해결책은 synthetic classloader

DynamicImport-Package
– 이 건 사용을 권장하지 않아.
=> 일관성이 없이 매번 실행할 때마다 문제가 있을 수도 있고 없을 수도 있다. 여러 버전을 사용할 수 있을 경우에 완전 운에 달린 게임이다.
– 프로토타입에서나 사용하고 제품에선 사용하지 말아라.

리소스 로딩
=> 클래스 로딩과 비슷한데 silent error가 발생한다.
– 리소르를 클래스와 동일한 곳에 둔다. 클래스에서 사용할 수 있도록 -> portable cnofig 자동으로 export 된다.

공유 자원
– META-INF/services
– 버저닝이 문제가 딜 수 있다.
=> 헤결 책은 extender

Externder 패턴
=> 번들 내부 리소스를 OSGi 서비스에서 사용가능하게 해준다.

웹 애플리케이션

오너쉽 문제 누가 로딩을 주도하는가?
– OSGi 플랫폼이?
– 웹 컨테이너가?
옵션
– HttpService
– Servlet Bridge
– ClassLoader bridge(스프링 DM 서버)

웹 애플리케이션에서 클래스 로딩
– WAR는 미리 정의되어 있는 클래스패스가 있다.
– OSGi에서는 뭔가가 필요하다. => 번들 처리 도구를 사용하거나, dm 서버가 해준다.

리소스 로딩
=> 스프링DM/dm 서버가 알아서 해준다.

서비스 Dynamics

OSGi 서비스
– 간적접인 계층
– 객체를 서비스 registry에 추가하거나 제거할 수 있다.
– 타입 필터링이 자동으로 적용된다.
– 서비스는 동적이다.(언제든 사라지고 나타날 수 있다.)
– OSGi 서비스는 싱글톤이다.

OSGi 서비스와 스프링 DM
– 그림
=> decoupling

서비스 Dynamics
– org.osgi.util.ServiceTracker
– Tracking Proxy(Spring DM) => 참조하던 서비스 없어지면 대체 가능한 다른 걸로 update 해준다.

다른 이슈
– 쓰레드 Context 클래스로더
– TCCL을 사용하지 말거나 스프링 DM/dm 서버처럼 관리하라.
– 쓰레딩
– 번들/애플리케이션 관리

결론
– STS, Spring DM, dm 서버를 사용하라. @.@

S1A – Building Large-Scale, Modular Software – 뢉 해럽

개념적인 통일성
– 분명한 “철학”
=> 설계는 싸고 개발은 비싸다.

복잡도 제어하기
=> 의존성을 제어해야 복잡도를 제어할 수 있다.

책임 주도 설계
=> 연관성이 깊은 데이터를 그룹핑해서 관리하는게 좋다
=> 유즈케이스랑 CRC 카드로 블라 블라…
=> dm 서버를 만들 때 CRC 카드를 사용했다.

Principal 모델
– Logical 패키징
– 동시성 => 에러를 어떻게 수정할 것인지 등등..

Formal methods: Z
=> 시뮬레이션 할 수 있어서 매우 유용하다.
– 하지만.. 난 모르겠다. 저게 뭔 기호인지;;; @.@ 그냥 코드를 보여달라고 코드를.. 이클립스에 프로젝트 띄워서 걍 보여달란 말이야~ ㅠ.ㅠ…

Formal methods: CSP
=> 프로세스와 이벤트를 표현해서 뭔가를 추적할 수 있는;;
– 역시 또 복잡해 보이는 기호..@.@ 아흑…

실용적인 조언
– 테스팅을 스킵하지마
– 리팩터링 하되 “looping” 하진마
– “design quiescent points”를 인식하라
– “analysis paralysis”를 기피하라

dm 서버 자료
– 시스템 뷰
– 모델 진화 과정

S1A – Advanced SpringSource DM Server by 뢉 해럽

와이어링
– 클래스 로딩: package import and export
– 객체 생성과 엮기: spring dm

Personality

synthetic context와 PAR

배포 파이프 라인
1. PAR 배포
2. personality 판별
3. ..

프로파일

고급 와이어링: 속성 사용하기
=> 같은 패키지 두 개 중에서 하나를 선택할 때 속성을 사용할 수 있다.

고급 와이어링: uses
=> 나중에 발생할 타입 캐스팅 문제를 조기에 방지

dm 서버 진단 기능
=> 콘솔에서 직접 분석해야 하는 걸 dm 서버가 알아서 해 준다.
=> ex) Import-Package, uses 진단 기능.

Java EE 애플리케이션 마이그레이션
(FormTags)
– 웹/서비스로 쪼개기
– 서비스에서는 구현체를 숨기고 인터페이스로 서비스를 공개
– web.xml에 별도의 OSGiContextLoader 사용한다.
– 서비스를 참조하는 reference를 만든다.

S1A – SpringSource dm Server Introduction by 뢉 해럽

SpringSource dm Server 소개

dm 서버
=> 자바 EE를 지원하려는게 아니라 OSGi 기반 배포 모델을 제공하기 위한 것이다. 매우 고객 지향적인(custom-oriented) 오픈 소스 프로젝트다.

배포
=>

Configurable
=> 여러분이 설치하고 싶은 걸 선택할 수 있다.

잠재적인 사용자 이익
=> 배포를 모듈 단위로 할 수 있다.
=> 쪼개서 개발할 수도 있고 유지보수 하기도 쉽다.

OSGi는 무언인가?
=> 유일한 모듈 시스템은 아니다. 하지만 10년이나 됐다. 그동안 많이 테스트 하고 검증되었다.

모듈
=> 정확히 어떤 패키지를 공개하고 사용할지 정의한다.(Strict Visibility rules)

모듈성
=> 타입 Dependency

모듈성:Import-Package
=> 버전 설정을 가능한 상세하게 할 것을 권장.

모듈성:Require-Bundle
=> 하이버네이트…, 하지만 패키지 중복 문제 발생 가능.

모듈성:Import-Bundle
=> 그래서.이걸 권장한다.

다음 레벨 모듈은 서비스.

서비스
=> 구현체는 감추고 타입으로 그 구현체를 참조할 수 있게한다.

데모
– greenpage 웹 애플리케이션 예제
– 모듈(app, db, jpa, web)

1. STS 실행
2. dm 서버 추가
3. dm 서버 홈 찾아주기
4. bundle 프로젝트 만들기
5. greenpage.web/모듈타입을 web으로/타겟 플랫폼을 dm 서버로 설정 next
6. Web-ContextPath 를 /greenpages   .. *.htm    next finish
7. META-INF/MANIFEST.MF 열고 설정 확인
8. src에 MODULE-INF/WEB-INF 폴더 추가
9. WEB-INF 폴더를 웹 폴더 루트로 jsp 추가
10. 컨트롤러 개발
11. Import-Library: org.springframework.spring:version=”[2.5.5.A,2.5.5.A]”
12. 컨트롤러 개발
13. META-INF/spring 풀더에 mudile-context.xml 만들기
14. 컴포넌트 스캔 추가해서 컨트롤러 빈 등록
15. 서버로 드래그 앤 드랍
16. 서버 실행
17. 404 에러 나는데 그건 뷰 파일이 없어서 그랬어. 복사해서 붙이고 뷰가 프리마커라서 프리마커 뷰 리졸버 추가해준다.
=> 로깅 메시지는 별도의 파일로 분리해 놨다.

0. web 모듈 빼준다.

1. greeenpage.app 모듈 추가
2. 패키지 추가
3. 인터페이스 추가
4. 구현체 추가
5. MANIFEST.MF에 Export-Package: greenpages.app:version=”1.0″ 추가
6. greenpage.web에서 Import-Package:greenpage.app 추가
7. 에러 나면 이클립스 프리퍼런스에서 패키지 의존성 추가
8. osgi-context.xml 파일 만들기
9. directory 서비스 등록.
10. module-context.xml 파일 만들기
11. Directoty 빈 등록
12. 서버로 드래그 앤 드랍
13. telnet localhost 2401 로 osgi 콘솔에 접근
14. osgi-reference.xml 만들기
15. osgi 레퍼런스 빈 등록 id=”directory” interface=”…

1. greenpages.db 모듈 추가
2. Import-Bundle: com.sprinsource.org.apache.commons.dbcp:version, …
3. datasource  빈 등록, osgi 서비스 등록
4. Import-Pacjage: javax.sql
5. 콘솔에서 설치한 번들과 서비스 확인

1.greenpages.jpa 모듈 추가
2. MANIFEST.MF에서 Import-Package: greenpages.app, javax.sql
3. 인터페이스 추가
4. 구현체 추가
5.  Import-Package에 javax.persistence 추가
6. Import-Library에 spring 추가
7. META-INF/spring 폴더에 module-context.xml 추가
8. 로드 타임 위버가 있네.. 왜 있지?
9. osgi-context.xml 추가
10. directory 서비스 추가
11. 드래그 앤 드랍
12. aspectj 없어서 실패.
13. Import-Library에 org.aspectj;version 1.6.1 추가
14. Import-Bundle: eclipse.persistence..
15. osgi 레퍼런스로 dataSource 등록

=> osgi:reference 의 filter 속성과 service의 속성 매칭으로 동일 인터페이스에 대한 여러 구현체 서비스 중에서 한 가지를 선택하게 할 수 있다.

1. Par 프로젝트 만들기
2. greenpage 만들기
3. Dependencies  탭에서 추가해주기.
4. 드래그 앤 드랍.

필요한 번들이 번들 저장소에 없는 경우
1. private class path 이용
2. osgi 번들로 만들어라.
3. 하난 뭐지?