레이블이 development인 게시물을 표시합니다. 모든 게시물 표시
레이블이 development인 게시물을 표시합니다. 모든 게시물 표시

2010년 4월 20일 화요일

Application Architect란?

몇년전 JCO 컨퍼런스에 참석한적이 있었습니다.
제가 들으려는 section은 사람들이 너무 많아서
들을 수가 없었습니다.
그래서 시간내서 온 것이 아까워서 사람들이
덜 몰리는 section쪽으로 갔습니다.

이동한 section의 컨퍼런스 주제는
"Application Architect" 였습니다.

※ 이하 Application Architect를 AA로 하겠습니다.

내용을 곰곰히 들어 보니 현재 제가 하고 있는
일도 포함이 되었고 반면에 내가 하지 않은
생소한 일도 있었습니다.

마지막에 강사님께서 앞으로
프로젝트에서 AA 롤은 반드시 필요 하며
또한 그에 따른 수요도 증가 할 것이다.

앞으로 고급 프로그래머라면 충분히 도전할
만한 가치가 있다 라고 말씀 하셨습니다.

레퍼런스가 끝나고 저를 포함한 참석했던 분들의
애매한 표정이 생각 납니다.

그러고 몇년이 지나서 최근 프로젝트에
조금씩 AA롤을 수행 하는 분들을 종종 만나게 됩니다.

그분들에게 "What's Application Architect?"
라고 물어보면 대답이 다들 제각각 이였습니다.
심지어 어떤곳은 TA (Technical Architect)라는용어를
사용하거나 프레임웍커(프레임웍 구축자)라고
하는 곳도 있었습니다.

혹시나 해서 웹 으로 검색을 해봐도
AA에 대한 정의가 개념적이지 구체적인
내용을 찾기가 어려웠습니다.

그렇다면 과연 AA는 프레임웍 과 공통 모듈을
구현 하는 사람인지 아니면 GoF의 디자인 패턴을
사용해서 멋지게 UML 설계를 하는 사람인지..

과연 여러분은 프로젝트에서 AA는 무엇이라고 생각
하십니까?

불명확한 실체에 대해서 한 개인이 정의를 내린다는 것은
상당히 조심스러운 행동이라고 생각 합니다.

그래서 주관적인 생각을 최대한 자제 하고
관련 책들과 자료 그리고 AA 담당자들과
대화에 근거 해서 설명 드리도록 하겠습니다.

  • Application Architect란?
시스템 특징에 적합한 설계와 구현의 지침인 아키텍쳐
를 작성하고, 이것을 개발팀 전원이 파알할 수 있도록
하는 것이다. 이를 통해 시스템의 품질을 끌어 올린다.
다수가 참여하는 프로젝트에서 아키텍트의 주된 업무는
설계 단계에 진행된다.
아키텍트는 설계 단계 전까지 준비한 아키텍쳐를 개발팀
에게 전달 하고, 팀원들이 아키텍쳐 설계서에 따라
설계와 구현을 할 수 있도록 지원 한다.

- 아키텍트 이야기 85p -

정보시스템에 대한 전반적인 지식과 시스템 구축
노하우를 보유한 경험이 풍부한 기술 전문가로서
프로젝트 전반에 대한 기술적인 총괄 책임을
담당한다.
아키텍처 정의에서 아키텍트가 수행
하여야 하는 업무로서 프로젝트에서 구축 하고자
하는 정보 시스템의 기반 구조를 정의한다.
기반구조의 정의에는 시스템 플랫폼,운영 및 개발환경
,표준 프로토콜,소프트웨어/하드웨어 솔루션 벤치마킹
및 선정 ,시스템 인터페이스 관계 정의,데이터 분산 및
통합 방안등 시스템의 기본적인 골격에 관련된
내용을 포함 한다.

- SI Project (전문가로 가는길) -

즉, 쉽게 설명하면 분석시에 업무담당자 한테
시스템 모모 필요 하니? 필요한 청사진 그리고
설계 단계에서 좀더 구체적으로 표준안 잡고
프레임웍 구축하고 개발자 교육하고
테스트 하는 일련에 Application A~Z까지
전체 총괄하는 롤이라고 이해 하시면 됩니다.

  • 아키텍트 수행 역할
- 프로젝트 착수 시 제안서와 계약서를 검토하여 기본적인
소프트웨어 및 하드웨어 아키텍쳐 환경에 대안 초안을
작성 한다.

- 분석 단계에서 전체 시스템에 대한 아키텍쳐 정의를 통해
소프트웨어 및 하드웨어 인프라 구조 정의,
서버 및 네트워크의 기본 모델 정의, 어플리케이션 모듈의
최상위 수준 모델링 등을 수행한다.

- 분석 단계에서 프로세스 모델링 및 데이터 모델링을 수행할 때
시스템 기본 아키텍처를 준수하도록 분석 산출물에
대한 검증을 수행한다.

- 소프트웨어 개발 환경 표준을 정의한다. 소프트웨어 개발을 위한
개발도구의 선정과 프로토타이핑를 주관한다.

- 설계 단계에서 프로그램 및 데이터베이스에 대한 설계 내용을
아키텍처 관점에서 표준의 준수 여부를 검증한다.

- 시스템 테스트 시나리오에서 아키텍쳐와 관련된 시스템 테스트
시나리오의 작성을 총괄 한다.

  • 아키텍트에게 요구 되는 것
※상,중,하는 역량의 중요도 입니다.

- 비용관리 (하)
- 일정 관리 (하)
- 요구 사항정의(하)
- 명세 수립 (중)
- 소프트웨어 설계 (상)
- 프로그래밍 (상)
- 개발 방법론 (상)
- 인프라 구축 (중)
- 테스트 방법 (중)
- 품질 관리 (하)

  • 실무에서 Application Architect
실무에서 만났던 대부분의 AA는
개발 주관 업체(일명:"을" Big3) 에서 하거나
컨설팀 업체에서 담당을 합니다.
(이유는 크리티컬한 업무이기 때문이죠^^)

그리고 전체적인 분석 및 설계 부분을
대부분 참여 하고 프레임웍 구축 및
코어 공통 모듈에 대해서는 거의
참여를 하지 않습니다.
그래서 대부분 AA + 전문 기술팀(Technical Architect) 또는
AA +TA로 구성된 단일 AA팀으로 구성이 되어있 있습니다.

개인적으로는 이러한 구성이 맞다고 생각 합니다.
과연 AA만으로 신기술과 오픈 소스 홍수 속에서
구현까지 잘 할수 있을까요?
그리고 장애복구,서버이중화등 비기능적 크리니컬
영역에 대해서도 해당 전문가와 co-work를 해야
합니다.
물론 단기 프로젝트거나 프로젝트 규모가
크지 않다면 충분히 혼자서도 가능 하겠죠.

  • AA 준비 하기...
사실 저도 AA는 아닙니다. (전 해커에 가깝다고
할까요 ㅋㅋ. 워낙 오픈소스 기반에 매쉬업을
좋아해서 )
이런 위치에서 AA 준비를 이렇게 하라고 말
하는 자체가 웃긴 일이지만 저 또한 AA가
되기 위해서 노력하는 사람으로써 말씀 드리겠습니다.

먼저 되도록 Big3 업체 또는 개발 전문 컨설팅 업체
에서 근무 하는 것이 좋다고 생각 합니다.
물론 들어가서 AA쪽으로 빠진다는 보장은 없습니다.
단 일반 SI 회사보다 기회가 많다는 뜻 입니다.

일반 SI 회사일경우는 정말 매니아적인
마인드가 필요 합니다.
프로젝트 특성상 SI는 업무 중심이기 때문에
기술적으로 깊이 있게 경험을 쌓기에는 제약
사항이 있습니다.
그렇기 때문에 더욱더 기술분야에 관심을
갖어야 할 것 같습니다.

초,중급일 경우 최신 트렌드 보다는
기술적 기본기에 투자를 많이 해야 합니다.
가끔 초,중급 개발자들 중에서 Spring의 한가지
기능을 사용했다고 해서 본인이 스킬이 뛰어난
사람이라고 착각 하는 경우를 종종 보게 됩니다.

초,중급분들한테 거의 아키텍처 관련된 구현을
맡기지 않습니다. 본인들이 교육을 받고 비지니스
로직을 구현할 정도의 센스만 실무에서 경험하고
나머지 시간은 집중적으로 core java,network,xml등
기본적인 기술을 연마 해야 합니다.
(프레임웍크는 업무에 편하지만 기술적인 부분은 점점
개발자를 바보로 만들고 있습니다.)

최소 7년간의 실무 경험이 필요 합니다.
AA는 절대로 물리적 시간과 경험이 필요 합니다.
7년까지는 구현에 대해서 많은 투자가 필요하고
그 이후는 설계에 더 무게 중심을 두어야 할 것 같습니다.
(요새 저도 설계쪽에 많은 시간을 투자 하고 있습니다.)

횡성수설 잘 알지도 못하면서 말씀 드렸네요
어쨌든 앞으로 시스템은 점점도 복잡하고
규모더 커쳐 가고 있습니다. 이럴때 AA의
역할은 절실히 대두되고 있습니다.
AA는 단기간에 만들어 지는 것이 아니며 양성하기도
쉽지 않습니다.
오직 열정과 매니아 정신만이 AA가 될수있다고
생각 합니다.

2010년 4월 19일 월요일

SI Project 패러다임!!

우리나라의 IT 프로젝트는 몇몇 특화된 것을 제외한
대부분이 J2EE 기반 SI 프로젝트일 것입니다.
하지만 이런 SI 프로젝트가 힘든 이유가 무엇
일까요 그 풀리지 않은 미스터리에 대한
의문점과 나름 해결 방법을 몇자 적어보려고
합니다.

  • 왜? 크리니컬 이슈는 항상 개발 막바지에 발생 하는가?

애자일의 가장 기본은 바로 test-first 입니다. 즉 개발 보다
테스트 환경구축 입니다.
공통모듈,프레임웍,비지니스 로직 개발 등 이러한 것보다
제일 먼저 아래와 같은 Activity가 선행이 되어야 할 것입니다.

- JUNIT과 같은 단위 테스트 탬플릿
- CI(Maven,Nexus,Hudson..등)를 위한 자동화 빌드
- Code Inspect (PMD..등)

※ 가끔 개발자 분들이 JUNIT을 상당히
귀찮은 존재로 생각을 하십니다.
개발할 것도 많은데 어느 세월에 Test
Junit을 만드냐고 합니다.
하지만 그건 전혀 잘못된 생각 입니다.
스프링이 Pojo인 이유는 바로 테스트를
편하게 하기 위해서 입니다.
그리고 저는 예를 들어서 게시판 CRUD 한 셋을
화면 포함해서 개발할때 비지니스로을
먼저 만들고 Junit으로실행 한다음
뷰단을 몰아서 작업 합니다.
그 중독성이란... 여러분 한번 제 방식이랑
여러분 방식이랑 CRUD 배틀 한번 해볼실까요^^
로직이 복잡할수록 그 공수 차이는 더 커집니다.

  • 왜? 화려한 시스템 아키텍쳐 청사진과 멋진 패턴로 구성된 UML 문서는 있음에도 불구 하고 프레임웍은 항상 불안 할까?

대부분 개발표준,프레임웍 구성등은 AA(Application Architecture)가
설계및 구축을 담당하고 있습니다. 하지만 최근 개발 동향을 보면
금융권을 제외한 (책임문제 때문인지 상용툴만 사용)한 일반
프로젝트는 스프링 기반에 오픈 소스로 구성 되었습니다.
물론 AA가 당연히 기술적인 부분을 많이 알고 있어야하지만
많은 오픈소스에 대해서 물리적으로 혼자서 해결 한다는 것은
무리라고 생각 합니다. 즉 전문 Technical 팀이 구성이 되어야
한다고 봅니다. AA 팀에 같이 소속이 되었던 별도의 공통파트이건
간에 이러한 팀이 AA와 기술적인 긴밀한 협조를 통해서
기술적 리딩을 해야 한다고 생각 합니다.

  • 일정은 있고 대화는 없는 건가?
PM과 PL의 제일 중요한 work는 당연 일정 관리 입니다.
하지만 일정관리 와 같은 중요도를 가지고 있는 것이
바로 프로젝트 팀원 관리 입니다.
하지만 이런 부분을 간과하는 경우가 많습니다.
가끔 저는 프로젝트가 이슈가 생겨서 중간에 투입
하는 경우가 있습니다. 그럴때 저는 일정이 연기되었거나
또는 기술적인 이슈가 생기는 것은 그다지 우려가 되지
않지만 PM,PL과 개발자 사이에 대화가 없으면
투입을 주저 합니다.
서로 대화가 없으면 솔직히 그프로젝트는 끝나다고 봅니다.
그 얘기는 개발자를 단지 도구나 툴로 밖에는 생각 하지
않는 다는 것입니다. 자 프로젝트 리스크를 제일 정확하고
잘알고 있는 사람이 누구일까요?
1.PM 2.PL 3.AA 4.개발자
정답은 전 개발자라고 생각 합니다. 개발자끼리 모여서
담배 피면 아마도 십중팔구
"이 프로젝트 큰일이다 답이 없다 답이" 이런 말들을
합니다.
개발자가 네거티브한거 인정 합니다. 하지만 틀린 얘기는
아닙니다. 일정만 강요하는 프로젝트에서는 절대로
왜 답이 없는지 말을 하지 않을 것입니다.

  • 누가 고급이고 누가 중급인가?

가끔 개발을 하게 되면 누가 고급이고 중급인지 분간을
할 수가 없습니다. 개인적으로 한분야에서 7년차까지는
구분이 필요하다고 생각합니다. 하지만 그 이상이 넘어가면
경력은 무의미 하다고 봅니다. 예전 개발 환경은 잘하는 사람,
못하는 사람 별 차이가 없었습니다.
하지만 최근에는 업무적/기술적 규모나 복잡도가 예전에
비해서 비교도 할 수 없을 정도로 커졌습니다.
즉 개개인의 능력 차이가 엄청나게 커졌습니다.
프로젝트 전문가 얘기를 들어보면 잘 하는 사람과
못하는 사람의 본수가 10본이상 차이가 난다고 합니다.
앞으로 인력을 선별할때 단순 년차 비교가 아니라
이전 플젝 PM이나 아니면 인맥 정보를 동원해서
그만큼 스킬이 있다면 중급이더라도 고급 대우를
해야 한다고 생각 합니다.
즉 경력보다는 인재를 확보해야 합니다.

  • 왜? 리스크가 있음에도 불구하고 그걸 바보처럼 한다고
  • 한 담당자에게만 책임을 몰빵하는가?

한번은 DA (Data Architecture)와 업무적으로 다툼적이 있었습니다.
Date형을 전부 varchar2(14)로 수정했다는 얘기 입니다.
그 런 큰 이슈를 전체 공지나 이슈화 하지 않았냐고 하니
"저번에 말씀 드렸잖아요. 그리고 개발문서에도 있구여"
그말을 듣는 순간 이단 옆차기 하고 싶은 충동이....
프로젝트하는 곳이 가정법원인가? 그래 나랑 개발팀이
몰랐다 글면 자기 혼자 사는 것인가? 어떻게 대놓고
책임을 회피하는 발언을 하는지...
그리고 한번은 PL이 저한테
"저 김과장님 이거 하는데 잘안되네..."
"내 제가 잠깐 볼게요"
다음날...
"그거 언제 되요? 늦어도 이번주까지는 되야 하는데"
음..................

  • 왜? 우리는 많은 경험을 하고도 또 경험을 해야 하는 것일까?

현실적으로 SI 프로젝트에 대해서 A~Z까지
다 알수는 없지만 각자 말못한 고충과
일들이 있을 것입니다.

무 조건 "갑",PM,PL,개발자 들을 비난할수는
없 습니다. 하지만 체질 개선은 반드시
필요하다고 생각 합니다.

사실 SI 프로젝트라는 것이 고객의 needs를 잘 분석해서
끈끈한 팀웍과 훌륭한 조직원들이서로 공유하고
리스크 최소화 하면서 결국 최고의 시스템을
고객에게 주는 것인데 무엇이 우리를 힘들게 하는 것인지
참...우리 모두 고민을 해야 할 것 같습니다. 마지막으로
"SI Project (전문가로 가는길)"이란 책에서 발췌한
"성공적인 프로젝트의 요건"에 대해서 말씀 드리고
마무리 하겠습니다.

1. 고객을 프로젝트에 최대한 깊이참여 하도록 한다.
2. 고객 경영진의 적극적인 후원을 얻어야 한다.
3. 인수인계를 위한 대비를 일찌감치 시작한다.
4. 80:20(인재) 률을 최대한 활용하라.
5. 고객의 속마음을 읽어라
6. 프로젝트팀을 잘 관리하라.

모드 성공적은 SI 프로젝트가 되길 바랍니다.

XP의 핵심 실천 사항

최근에 "SI Project (전무가로 가는길)" 책을 읽으면서
XP(eXtreme Programming)의 핵심 실천 사항이
잘 정리가 되어 있어서 발췌해 봅니다.
참고로 SI 개발자 분들께서는 반드시
꼭 필독서라고 생각 합니다.

  • 전체가 한 팀이다 (whole team)
XP 프로젝트를 위한 프로젝트팀은 고객과 개발자
그리고 프로젝트 관리자로 구성된다.
이들 구성원들은 기존 프로젝트 관리방법론에서 개발을
위해 여러 파트로 구분하던 것을 하나의 팀으로 운영 하면서
User Story를 중심으로 개발 계획 및 배포계획을 작성하고
이에 따라 반복적 개발 방식으로 개발을 추진한다.

  • 계획 게임 (planning game)
고객과 함께 하는 게임이다. 고객이 User Story를 작성하면
개발자는 이를 분석하여 개발에 필요한 시간을
구하고 고객은 여러 User Story들에 대해 개발에
우선순위를 부여하고 개발을 위한 배포계획을 개발자와
함께 수립하여 개발을 진행 한다.

  • 고객이 테스트 한다 (customer tests)
모든 User Story들은 개발이 완료되면 단위 테스트를 거치고 인수
테스트를 수행한다.
이때 인수 테스트를 위한 기준을 고객이 지정하고 인수 테스트에
고객이 참여함으로써 User Story의 구현이 완벽하게 되었는가를
검증 한다.

  • 작은 배포 (small release)
모든 XP에서의 시스템 개발은 시스템 규모에 관계없이 일정한
크기의 User Story로부터 시작되면 이러한 작은 User
Story들이 모여 하나의 시스템을 구성한다.
따라서 User Story의 구현에 따른 작은 배포가 수없이
많은 횟수로 이루어지며 이 때마다 자동화된 테스트 환경에
의해 시스템의 통합 테스트가 이루어지게 된다. XP의
기본 사상으로서 테스트의 반복은 시스템 품질
향상을 위한 초석이다.

  • 단순한 설계 (simple design)
프로그램을 하기 위한 설계의 일환으로 기립회의를 추진 한다.
개발자들이 둥글게 둘러서서 시스템의 설계를 검토하는
짧은 회의를 설계안에 대한 의견을 공유하며 여러
설계안 중에서 가장 단순한 설계안을 채택함으로써 시스템
의 복잡도를 낮추고 품질을 높이는 전략을 채택하고 있다.

  • 짝 프로그래밍 (pair programming)
팀원들 간에 교대로 두 명의 프로그래머가 짝을 이루어 하나의
User Story를 설계하고 구현함으로써 팀 의사소통 활성화
및 시스템 전반에 대한 품질 향상과 팀원들의 기술력
확산에 긍정적인 결과를 유도할 수 있다.

  • 테스트 중심 개발 (test-driven development)
테스트 케이스를 기반으로 자동화된 테스트 환경을 프로그램
이전에 구축하고 프로그램 과정에서 지속적인 테스트를
수행하여 프로그램의 품질을 높인다. 효율적인
테스트 환경의 구축을 위해 자동화된 테스트 도구의
활용은 필수적이다.

  • 설계의 개선 (design improvement)
리팩토링으로 대표되는 XP의 지속적인 설계의 개선은 모든 객체에
대해 가능한 가장 효율적인 기능으로 재구성하는 것을 권장한다.
리팩토링의 지향점은 객체의 기능을 유지하면서 가능한 단순한
설계와 기능의 프로그램으로 재구성하는 것이다.

  • 지속적인 통합 (continuos intergration)
수 많은 User Story로 세분화된 개발 단위 중심의 배포 계획에
의한 지속적인 시스템 통합 및 테스트는 시스템을
보다 안정적으로 개발할 수 있는 환경을 제공 한다.
계속되는 작은 배포와 이에 따른 지속적인 통합 절차 및
테스트의 수행으로 프로그램에서 오류는 제거되고
프로그램 설계의 개선으로 효율성 및 성능은 향상된다.

  • 선택적 코드 소유권한 (collective code ownership)
여러 개발자들이 자유로이 다른 개발자의 소스코드에 대한
수정 권한을 갖도록 함으로써 다양한 관점에서의
프로그램 설계 개선이 이루어진다. 또한 이 과정에서
중복되는 프로그램의 기능이 제거되며
프로그램 간의 인터페이스 문제들이 최소화되고 개발자의
안목이 향상 된다.

  • 코딩 표준 (coding standard)
XP에서의 프로그램은 프로젝트 전체 개발팀에 대한 코딩의
표준 준수를 기준으로 수행한다.
이 방침은 다른 개발 방법론에서도 주요한 개발 전략이다.
그러나 XP에서는 짝 프로그래밍,선택적 코드 소유권한,
설계의 개선 등의 전략을 통해 어떠한 다른 개발방법론보다
코딩 표준이 효율적으로 적용될 수 있는 환경을 제공한다. 이 코딩
표준은 전체 시스템을 마치 한명의 뛰어난 프로그래머가 개발
한 것과 같은 효과를 가져온다.

  • 은유법 (metaphor)

프로젝트 팀 내에서 개발하고 있는 기능들에 대한 설명을 누구나 이해할
수 있는 은유적인 기법을 통해 표현하려고 노력 한다.
딱딱한 설명 대신 전체 시스템의 기능을 상징적으로
표현할 수 있는 쉬운 표현의 작성을 위해 노력하는 과정에서 시스템의
기능에 대한 보다 깊은 이해를 불러 오는 효과가 있다.

  • 주당 40시간 (40 hour/week)
소프트웨어의 개발을 지속적인 행보로 오랜 시간 계속
수행할 수 있도록 한다.마치 마라톤을 하듯이 순간의
스퍼트로 전체적인 리듬과 페이스를 잃지 않도록
꾸준하면서도 지치지 않는 시스템 개발을 위해 주당
40시간의 개발 작업을 준수하도록 한다. 무리한 야근은
개발자들의 생선성을 저하하며 시스템의 품질을 떨어
뜨리고 장기간의 프로젝트 수행을 어렵게 만든다.

2010년 4월 1일 목요일

Validation 정책에 대해서....

오늘의 주제는 데이터 Validation에 대한 내용이며 개발적인
측명 보다는 QA팀이나 보안검수팀에서 한번 정도 고려
해야 할 정책적인 얘기를 하고자 합니다.
데이터 Validation은 클라이언 사이드의 자바 스크립트
검증과 서버사이드 검증이 있습니다.
쿨 하게 결론 부터 말하자면
"서버 검증만 하자는 것입니다."

  • View Validation을 꼭 사용 하는 경우
(1) 서버 Validation 구현을 기술적으로 자신이 없어서
View Validation만 하는걸로 현업과 협의 된경우

(2) 포털 사이트와 같이 많은 사용자가 있는 곳에서
이벤트 같은 페이지일 경우 (서버로드 최소화 하기 위해서)

(3) 일정에 쪼겨서 검수 항목에 서버 Validation은 제외한 경우

이렇게 3가지 경우 외에는 굳이 View Validation을 할 필요가
없다고생각 합니다.

한번은 제가 보안 검증팀에 View Validation을 빼고
서버 Validation만 하자고 했더니 절대 안된다고 했습니다.
그래서 제가 why? you hate me?
했더니 이해 할수 없는 두가지 답변을 친절하게
해주었습니다.
보안적인 문제와 서버로드 최소를 위한 목적이였습니다.

그래서 저는 위 의 2가지에 대한 반론을 제시 했습니다.
첫번째 보안적인 문제
ㅋㅋ 갑자기 웃음이 나오네요 언제부터 자바 스크립트가
보안 스크립트 였습니까.
HTML 다운 받아서 검증 스크립트 주석 처리하고
submit 하면 안날라 갑니까
도대체 모가 보안 인지 알 수가 없습니다.

두번째 서버 로드 최소화 문제
제가 질문 했던 시스템은 일반 사용자 상대로
외부 노출되는 시스템이 아닌 내부 시스템
이였습니다. 사용자가 정말 많아 봤자 천명이
되지를 않습니다. 그리고 서버에서 Validation은
무거운 작업(DB Connection,XML Parsing,TCP connet)
없이 데이터 검증만 하면 바로 리턴 됩니다.
즉 서버에 라이트한 작업을 요청 하는 것이지요
그리고 일반적으로 데이터를 submit 할 경우
아무 생각없이 글을 작성하지 않습니다.
다들 신중하게 작성을 하기 때문에 경험상
동시에 많은 request가 집중 되지 않습니다.
정말 아파트 분양 입력 화면이나 대박 이벤트
화면이 아니고서는 대부분 서버 사이드에서
처리 해도 됩니다.

  • Server Validation의 장점
프로젝트를 하다 보면 대부분이 서버 컴포넌트
개발 보다 뷰 개발에 더 시간이 올래 걸립니다.
특히나 View 검증 로직에 대한 공수는 은근히
걸립니다.
Server Validation을 하게 되면 View 검증 로직에
대한 공수를 줄일 수 있습니다.
또한 한번에 전체 입력에 대한 검증 실패 메세지
를 보여줄수가 있습니다.
"아이디를 입력 하세요" alert 뜨고 - 다시 입력 후 저장 합니다.
"아이디는 영문이여야 합니다." 또 alert 뜨고
아니 한번에 다 보여주면 얼마나 친절 합니까
외국 사이트는 많이들 이런 컨셉으로 Validation
을 진행 하고 있습니다.

  • 둘다 만족하는 방법 (valang,apache validation)
Server Side에서 Validation 로직을 View에서도 적용 할수
있는 기술적인 것들이 있습니다. 대표적인 것이
apache에서 제공하는 validation과 valang 입니다.
전 개인적으로 이건 최악 입니다.
너무 시스템을 복잡하고 지저분하게 만듭니다.
어떨때는 안하는 것만 못하게 되어 버립니다.
굳이 저렇게 까지 복잡하게 공수를 투자해야
한다는건 개발자의기술적 욕심입니다.

2010년 3월 31일 수요일

Spring 기반 오픈 소스 프로젝트에 참여 하실분!!

예전 부터 오픈 소스를 정말 해보고 싶었는데 현실적인
바쁜 일정 과 게으름 때문에 마음 속으로만 생각을 하고
있었습니다.
그러던 중 최근에 프로젝트가 끝나고 개인적인 시간이
조금 생기면서 아~~ 지금아니면 다시는 못할 것 같은
생각이 들어서 일단 고고씽 하기로 했습니다.

틈틈히 일주일동안 google code에서 프로젝트를 생성하고
개발에 관련된 웹 문서 작업(개발자 가이드,프로젝트 소개..)
과 SVN 설정 및 개발 템플릿 개발까지...
일단 기본적인 셋팅은 완료가 되었습니다.

막상 준비를 해보니 Open Source 를 하시는 분들이나 또는 좋은 정보를
블로그나 책을통해서 전달 하신 분들이 정말 대단하는 걸
느끼게 되었습니다. 뛰어난 개발 스킬 과 아키텍쳐도
대단 하지만 그것보다 더 대단한건 개발에 대한 애정
과 열정 같습니다.
(이분들에 비하면 아직 멀었음)

  • Consider
프로젝트를 시작 하기 앞서 과연 어떤 프로젝트를 해야 할지
정말 고민을 많이 했습니다.

작은 단위의 개발 규모
무엇보다 척박한 우리 나라 개발 현실 속에서 과연 심신이 지친
개발자 분들이 일 외에 또다른 개발에 참여 한다는 것은
제가 생각해도 가혹한 일이라고 생각이 듭니다.
그래서 되도록 참여하 시는분들이 작은 단위로
참여 해야 한다고 생각을 했습니다.

헙업없이 최대한 자유 스러운 개발
첫번째와 비슷한 맥락 입니다. 개발 참여 하는것도
쉽지 않은데 서로 간에 협업 하면서 하는 것보가 프로젝트의
컨셉은 지키되 되도록 참여하는 개개인이 간섭 없이
독고다이 할 수있는 컨셉으로 가야 한다고 생각 했습니다.

실무에서 바로 써먹을 수 있어야 한다는 것입니다.
정말 마음 같아서는 spring container나 hibernate
같은 훌륭한 오픈 소스를 만들어서 세계적으로
한국의 위상을 세우고 싶지만 현실과 너무
괴리감이 있습니다.

  • Concept (스프링 기반 Best Practice 프로젝트)
개발 리딩 과 프레임웍 구축 업무를 주로
하고 있는 저는 자세히 생각해 보니깐 반복된
일을 매 프로젝트마다 하고 있었습니다.
이미 이것저것 다 붙은 무거운 프로젝트에서
필요한 부분 빼서 또 재구축 하는 것이 였습니다.
그리고 구현해야 할 부분을 찾다 보면
대다수의 블러그들이 부분적으로 코드를
설명해서 결국에는 스프링 메뉴얼을 보고
구축 하게 되었습니다.
이러한 반복적인 시간 낭비를 줄이기 위해서
스프링 기반에 Best Practice를 위한 오픈 소스를
생각을 했습니다. 만약 DWR + Spring MVC 연동에
대한 Best Practice를 만들면 굳이 db 붙이고 Service,
DAO 필요없이 컨트롤러 테스트만 하면 끝 입니다.
물론 DB가 필요한 JPA Best Practice라면 틀리 겠지만
어쨌든 딱 필요한 Spring 기반 Best Practice를
모은 오픈 소스를 진행 하면 서로 반복을 줄이고
그 시간에 미구현된 Best Practice를 만드는 것이
훨씬 낫다고 생각 합니다.

  • Participation
컨셉 자체가 스프링을 스터드 하기 위한 성향이 강하고
저 또한 아직 허접한 개발자 입니다. 잘하고 못하고를
떠나서 열정과 관심 있는 분들은 누구나 참여 가능 합니다.
관심 있으신 분들은 오픈소스 웹사이트(http://code.google.com/p/springshowcase/)
를 참고 하시고 springorg@gmail.com으로 메일 부탁 드립니다.
4월 중순 경에 간단하게 오픈 소스 개발 관련해서 강남역에서
세미나를 할 예정입니다.

2010년 3월 18일 목요일

Spring Annotation 설정시 유의 사항

Spring을 Web Application에서 사용할때 ApplicationContext가
두개의 Context로 관리 됩니다.
각각의 ApplicationContext 설정 방법중
하나는 ServletListener를 구현한 "ContextLoaderListener"
와 나머지 하나는 Servlet을 구현한 "DispatcherServlet"
입니다.

 <listener>
<listener-lass>org.springframework.web.context.ContextLoaderListener
</listener-lass>
</listener>
.....
<servlet>
<servlet-name>webAppServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:/webapp-servlet.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

이 두 ApplicationContext는
부모(ContextLoaderListener)-> 자식(DispatcherServlet)
관계로 되어 있습니다.
이런 구조를 가지고 있어서 주로 부모 ApplicationContext
에는 Service,DAO,DataSource,Transaction 클래스들을
설정하고 자식 ApplicationContext에는
Controller를 설정 합니다.

※단 부모에서는 자식을 참조 할수 없음

스프링을 설정할때 Annotation을 설정하려면 아래와
같이 설정을 해야 합니다.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config/>
</beans>


하지만 위와 같은 선언은 반드시 같은 ApplicationContext
에 위치하는 것에만 적용이 됩니다.
즉 "DispatcherServlet"에 위와 같은
xml을 설정하게 되면 "@Autowired"를 통해서
빈을 검색할때 부모 ApplicationContext에 존재하는 빈들을
참조 할 수 없습니다.
즉 Service,DAO 빈들을 참조 할 수 없다는 얘기 입니다.
그래서 반드시 저 선언은 "ContextLoaderListener" 에
선언을 해야 합니다.
참고 하시기 바랍니다.

2010년 3월 15일 월요일

한국형 J2EE 스펙 (egovFrame 기반)

최근에 정부에서 스프링 기반에 "egovFrame" 이라는
전자 정부 프레임웍을 만들었습니다.
개인적으로 프레임웍을 만들었다는 의의 보단
정부 차원에서 오픈 소스 사용에 대해서 인정을 했다는 점과
그러한 오픈 소스들을 마치 한국형 J2EE 스펙화 했다는
점이 제일 맘에 듭니다.
그래서 제가 "egovFrame"을 기준 + 개인적으로 추천하는 오픈소스
를 추가해서 한국형 J2EE 스펙(? ㅋㅋ) 을 그려 봤습니다.

2010년 3월 8일 월요일

이클립스에서 Derby 사용 하기

DBMS 관련되 오픈 소스들이 많이 나와 있습니다.
HSQL,SQLLight,Apache Derby 등이 있습니다.
이들 DB의 사용하는 이유는 오픈 소스라는 점과
생각 보다 높은 퍼포먼스와 트랜잭션을
안전성 있게 보장한다는 점이 매력이 있습니다.
개인적으로는 Hibernate와 같은 JPA 테스트를
위해서 사용 하고 있습니다.
그래서 Apache Derby에 대한 내용 보다는
(please.. googling!)
테스트를 위해서 이클립스에서 쉽게
설치하고 구동 및 사용법에 대해서 말씀
드리려고 합니다.
본 내용은 Derby 사이트에서 제공한 내용을
재구성 했습니다.
(http://db.apache.org/derby/integrate/plugin_help/start_toc.html)
  • 설치하기 (Derby & Eclipse)
Apache Derby 다운로드 사이트에 접속 합니다.
(http://db.apache.org/derby/derby_downloads.html#How+to+build+Derby)
Derby 최신 버전의 다운로드 링크를 선택 합니다.
(글을 쓰고 있는 시점에서 "10.5.3.0"이 최근 버전이네요)

이동한 페이지 하단 부분에 보면 아래와 같이 zip 파일을
볼수 있습니다.
두개 파일을 다운 로드 받습니다.
(derby_core_plugin_10.5.3.zip,derby_ui_doc_plugin_1.1.2.zip)

각 파일들을 압축 해제 하면 각각 "plugin" 디렉토리가 존재 합니다.
이 디렉토리를 이클립스 "plugin" 디렉토리로 덮어씌기를 합니다.
예상을 한분들도 있겠지만 이클립스 플러그인 추가하는 것입니다.
적용이 끝나면 이클립스를 리붓 합니다.
  • 서버 기동하기
새롭게 적용된 이클립스가 실행 되면
개발 하고자 하는 신규 프로젝트를 생성 합니다.
(Maven 프로젝트를 하던 WTP로 생성하던 일반 자바 프로젝트던
상관없습니다.)
생선된 프로젝트를 선택 후 "Right Click" 하면 서브 메뉴바에
"Apache Derby" - "Add Apache Derby nature"를 선택 합니다.


적용 하고 나면 "Apache Derby" 메뉴에 추가로 서브 메뉴들이
추가 된것을 볼 수 있습니다.
"Start Derby Network Server"를 실행 합니다.

기동 하게 되면 아래와 같은 메세지 창이 출력 됩니다. Derby는 기본 Port
는 1527번을 사용 합니다.

"OK" 버튼을 선택하면 서버가 기동 됩니다.
즉 오라클일 경우 DB 인스턴스가 Startup에서 리스너가
대기중인 상태라고 볼 수 있습니다.

  • SQL 실행 하기
이제 Apache Derby를 사용하는 환경 설정을 끝났습니다.
그러면 과연 어떻게 접속하고 SQL를 질의하는 방법에
대해서 말씀 드리겠습니다.
오라클에서 SQL를 실행 하려면 "SqlPlus"를 사용해서
질의를 할 수 있습니다.(물론 다른툴 쓰시겠죠^^)
이러한 콘솔을 제공하는 것이 "IJ"란 유틸리티 입니다.
서브 메뉴를 오픈 합니다.
"Apache Derby" - "Run SQL Script using 'ij'"를 실행 합니다.

실행 하면 "IJ>" 커서 명령을 기다리고 있습니다.
아래와 같이 SQL 스크립트를 질의 합니다.

connect 'jdbc:derby://localhost:1527/myDB;create=true;user=me;password=mine';
insert into restaurants values (4, 'Grande Burrito', 'Oakland');
update restaurants set city = 'Ukiah' where name = 'Irifunes';
select * from restaurants;
disconnect;
exit;
질의 후 결과 화면이 아래와 같이 출력 됩니다.

2010년 2월 25일 목요일

WAS는 가고 OAS 시대가 도래 한다.(Past WAS,Comming OAS)

아 이제 WAS(Web Application Server) 시대는 가고
새로운 OAS (Open Application Server) 시대가 올듯 합니다.
아래는 꿈의 플랫폼 청사진

OSGi란..

최근에 제가 가장 관심을 갖고 있는 분야가 OSGi 입니다.
(특히 Spring DM Server ^^)
OSGi는 오래전부터 그들만의 리그 처럼 묵묵히 조용히 지내고 있었던
기술 이였습니다. 그러다가 최근에 스마트폰 광풍에 힘입어
구글 안드로이가 출시되면서 급 호감을 갖게 되었습니다.
(구글 안드로이드는 OSGi 플랫폼으로 구성되었죠)
거기다가 소형 가전기기 전용 플랫폼이였던 OSGi가
SpringSource에서 차세대 J2EE 플랫폼으로
Spring DM Server를 릴리즈 함으로 이제는 반드시
알아야 할 기술이 되었습니다.
그러면 과연 OSGi는 어느날 갑자기 안드로메다에서 온 기술일까요?
일반 블로그나 사이트에서 OSGi 관련 내용을 보면 개괄적인 내용과
다소 쉽게 이해가 가지 않은 개념(Bundle,Activator,Service)들에
대한 이론적 설명이 많았습니다.
그래서 제가 OSGi를 공부하면서 detail한 설명 보다
개발자로써 조금이나마 전체적인 맥을 잡고 OSGi에
대해서 두려움 없이 접근하시는데 도움이 되고자 말씀
드립니다.

  • OSGi's Feature
Apress Spring DM Server를 보면 아래와 같이 OSGi 특징에 대해서
기술되어 있습니다.

(1) OSGi는 전체 시스템를 restart 하지 않고 각가의 모듈을 동적으로 추가,변경,삭제를
할 수 있습니다.

(2) OSGi는 전체 시스템에 버전이 각각 다른 모듈을 동시에 사용 할 수 있습니다.

(3) OSGi는 각 모듈관에 의존성을 관리 합니다.

(4) OSGi는 SOA처럼 각 모듈을 서비스 레지스터리에 등록해서 필요한 한 곳에서
가져다가 쉽게 재사용 할 수 있습니다.


  • How to Use OSGi
위에서 저도 모르게 OSGi에 대한 개괄적인 설명을 했네요 쩝.
자 이제 글면 과연 OSGi를 어떻게 사용하는지 말씀 드리겠습니다.
외국에서는 OSGi Container라고 얘기를 합니다.
Container라함은 JVM 상에서 오브젝트에 대해서 생명주기
를 관리하는 서버라고 생각 하시면 됩니다.
비슷한 것들이 Servlet Container,EJB Container들이 있습니다.
(급 어려운얘기? Sorry)
쉽게 말해서 Servlet Container에서 동작하는 모듈을 만드려면
그냥 만드는 것이 아니라 Servlet을 만들어야만 동작하듯
OSGi Container도 마찬가지로 Bundle이라는 것을 만들어서 동작을
합니다.
OSGi 기동 방법은
java -jar org.eclipse.osgi._3.4.3....jar -console
이렇게 컨테이너를 띄우고 번들들을 인식하도록 하면 Container가
뜨면서 번들을 초기화 합니다. 마치 Servlet들을 초기화
하듯이 말이죠
이렇게 OSGi Container가 뜨고 나면 콘솔을 통해서 현재 등록된
번들의 상태를 화면을 통해서 볼 수가 있습니다.
마치 DOS상에서 커맨드를 치듯이 말이죠.
명령어를 통해서 번들을 추가하고,수정하고,삭제하고
즉 정리 하면 서블릿 Container 처럼 OSGi Container를
실행하고 OSGi에서 인식할수 있는 bundle 스펙을
구현해서 넣으면 됩니다. 그리고 위에서 동적으로
변경할수 있다는 얘기들은 마치 Servlet를 동적으로 추가,변경,삭제
할 수있다는 얘기와 같습니다.

  • OSGi Container 종류
Servlet 컨테이너도 jetty,tomcat,jboss 처럼 다양하게 있듯이
OSGi 컨테이너도 다양하게 있습니다.
Eclipse에서 제공하는 equinox,Apache에서 제공하는 Felix등
있습니다.
기본적으로 OSGi 스펙들을 구현한 Container들이며
자기 입맛에 맛는 Container를 사용 하시면 됩니다.
저는 개인적으로 아무래도 equinox를 사용합니다.
(이유인즉 spring dm이 이넘을 사용하거든요..)
  • Spring dm Server
SpringSource에서 OSGi 기반 J2EE 플랫폼이 Spring dm 입니다.
제가 정말 궁금한 것은 어떻게 OSGi가 어떻게 웹 어플리케이션을
지원할까 하는 문제 입니다. 물론 OSGi 자체에서 제공하는
Http 서비스가 있습니다.
하지만 제약사항이 많고 다소 허접합니다. 이유인즉
war 형식을 지원하지 않습니다. 아무래도 가전기기에 올라가다
보니 http 기능을 최소화 한것 같습니다.
그래서 우리가 사용하는 war 형태의 어플리케이션을
구동하기를 원합니다.
OSGi를 모른 상태에서 생각이 톰캣안에서 OSGi를 넣는건가
이런 생각을 했습니다.
하지만 그런 개념이 아니였습니다.
대장은 OSGi가 일단 구동 합니다. 그리고 톰캣이나 jetty 서버를
번들화 합니다.(이건 이미 spring source respository에 maven
형태로 되어 있습니다.)
그리고 내가 만든 웹 어플을 번들로 추가 합니다.
즉 OSGi 컨테이너가 구동하고
tomcat server bundle,my war bundle
이렇게 구동합니다. tomcat server bundle은 현재 번들 중에서
패키징이 "war"이거나 "WEB-INF" 디렉토리가 있으면
찾아서 디플로이 합니다.
모든게 OSGi 컨테이너안에서 이루어 집니다.

  • 마무리
참 제가 생각해도 주저리 주저리 적었지만 OSGi에 대해서
블러깅 한다는게 정말 한계가 있네요
앞으로 OSGi 관련해서 틈틈히 블로깅 하려고 합니다.
아무튼 OSGi 컨테이너를 사용하고 거기에 동작하는 모듈 스펙은
bundle이며 컨테이너에서 동작하기 때문에 당연히 생명주기가 있겠죠
생명주기에 맞게 처리 하고 콘솔을 통해서 restart 없이
모듈상태를 바꾸고 이게 대부분이라고 할 수있습니다.
이런 관점으로 OSGi를 생각하고 접근 하시면 좀더 편하게
이해 하실것 같습니다.
우리나라에서 "OSGi & Spring DM" 책이 출간 되었습니다.
개인적으로 이책에 도움을 많이 받았습니다.
소스 중심이라서 좀 지루할 수 있지만 예제가 정말 잘되어
있어서 좋습니다.
꼭 읽어 보시기 바랍니다.
이제 삽질만 남았네요 ㅋㅋ

2010년 2월 16일 화요일

Weblogic 개발시 유의 사항

오늘 허드슨으로 Weblogic 빌드 테스트를 진행중에 두 가지 중요한
사실을 알게 되었습니다.
막상 이슈를 해결하고 보니 허탈 하지만 그래도 모르면 많이
삽질을 할 것 같아서 말씀 드립니다.

  • PathMatchingResourcePatternResolver 이슈
"PathMatchingResourcePatternResolver" 클래스는 매우 유용한
클래스 입니다. 이 클래스 용도는 파일 위치를 와일드 카드를
사용해서 가져 올수 있습니다.
(실제로 spring context 로드시 이 클래스를 사용함)
예를 들어서 "WEB-INF/config/*.xml" 이렇게 선언하면 와일드
카드가 적용되서 저 패턴에 해당하는 파일들을 읽어 옵니다.
만약 저 클래스를 사용하지 않는다면 복잡한 유틸성 클래스를
만들어야 겠죠.
저는 이 클래스를 사용해서 properties로 된 config성 파일들을
로드해서 초기화 합니다.
Resource[] resources;
PathMatchingResourcePatternResolver prcrr;
int resourceCnt;
resourceCnt = 0;
prcrr = new PathMatchingResourcePatternResolver();
resources = prcrr.getResources("classpath:/config/*.properties");

6 Line : Ant 패턴으로 해당 파일들의 정보를 배열 형태로 가져옵니다.

문제는 톰캣,Jboss 사용시에는 전혀 문제가 되지 않는데 weblogic에서
사용하면 해당 파일을 찾지 못하는 경우가 발생 했습니다.
별짓을 다해도 소용이 없다가 찾아 보니 경로를 아래와
같이 수정해서 선언 해야 한다는 것입니다.
"classpath:/config/*.properties" => "classpath*:/config/*.properties"
수정된 부분은 "classpath"앞에 "*"를 붙여야 한다는 것입니다.
아래는 소스상에서 spring context를 가져오는 예제 입니다.
private static final String SPRING_CONFIG_FILE = "classpath:/*SpringConfig.xml";
ApplicationContext context = new ClassPathXmlApplicationContext(SPRING_CONFIG_FILE) ;


이부분도 "classpath*:/*SpringConfig.xml" 변경해야 weblogic에서
인식이 됩니다.
web.xml에서 "contextConfigLocation" 선언시 앞으로
"classpath"를 "classpath*"로 변경해서 설정하는
습관이 필요 합니다.

  • getServletContextName 이슈

image,css,js등 웹 리소스의 경로를 지정할때 "getServletContextName()" 메서드를
통해서 하드코딩 하지 않고 개발 환경이든 운영환경이든 상관없이
가져와서 경로를 맵핑 하도록 하는 유틸 클래스가 있었습니다.
그런데 이상하게도 weblogic console에서는 Context 이름이
"Webapp"로 되어 있는데 이미지가 다깨져서 나오는 것입니다.
그래서 jsp에서 "pageContext.getServletContextName()"를
해보니 "MyWebapp"로 출력이 되었습니다.
콘솔이나 호출시 Context는 "Webapp"인데 어떻게
"getServletContextName()"를 호출하면 다른 이름이 나오는지
정말 돌기 일보 직전...
확인해 보니 web.xml에서 아래와 같이 수정해야 합니다.
<display-name>Webapp</display-name>


즉 "getServletContextName()" 호출하면 weblogic에서는
"display-name" 태그에 명시한 이름이 리턴되게 되어 있습니다.
ZEUS도 마찬가지 입니다.
그래서 weblogic 설정시 반드시 콘솔에서 설정한 context 명과
web.xml의 "display-name" 태그와 일치하도록 하는 습관이
필요 합니다.

  • Weblogic은 구리다(?)
저도 이런 헤프닝을 치른 후에 weblogic에 대해서 불만이 많았습니다.
tomcat에서 개발된 webapp는 jboss에서는 무리없이 설치가
되는데 유독 weblogic만 호환이 안될까 하고 다소
회의적인 생각을 했습니다. 자바는 플랫폼 독립적인 언어인데
그 말과 일치 하지 않게 WAS에 의존적이지....
누구나 많은 경험을 했을 것입니다. tomcat으로 개발 하고
weblogic에서 빌드할때 초조하고 불안한 마음을 ...
하지만 곰곰히 생각해보니 weblogic은 표준에 대해서
엄격한 WAS 입니다. 어떻게 보면 우리가 J2EE 스펙을
잘모르고 weblogic만 탓하는건 아닐까 하는 생각이
들더군요.무조건 벤더만 탓하지 말고 먼저 내가
표준을 잘지키는지 부터 의심해 봐야 할 것 같습니다.

2010년 2월 10일 수요일

동적으로 오픈소스 자바스크립트 라이브러리 로드하기

일반적으로 오픈 소스 자바스크립트를 사용 하려면 대부분
해당 사이트의 다운로드 사이트에 접속해서 "js" 파일을
다운로드 한후 <script src="jquery.js"> 형태로 사용합니다.
만약 jquery외에 다른 라이브러리를 사용하고자 할때는 똑같은
일을 반복해서 설정 하겠죠.
그래서 오늘은 이러한 라이브러리들을 쉽고 간편하게 설치 없이
사용 하는 방법에 대해서 말씀 드리겠습니다.
제가 말씀 드린 내용은
구글 Ajax 관련 사이트(http://code.google.com/intl/ko-KR/apis/ajaxlibs/)
에 기술된 내용들 입니다.

  • Load Ajax Library
동적으로 라이브러리를 로드하는 방법은 구글에서 제공하는 방법을
씁니다. 예를 들어서 jquery 와 prototype 을 동시에 사용하고
싶다면 아래와 같이 선언 후 사용 하시면 됩니다.

<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("jquery", "1.4.0");
google.load("prototype", "1.6.0.2");
</script>

1 Line : Google Ajax 라이브러리를 import 합니다.

3,4 Line: 사용하려는 Ajax 오픈소스 라이브러리를 로드 합니다.

  • Example



<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("jquery", "1.4.0");
google.load("prototype", "1.6.0.2");

google.setOnLoadCallback(function() {
jQuery(document).ready(function(){
jQuery("button:first").click(function(){
jq();
});
});
});

function jq() {
jQuery("#unique").show();
}

function pt(){
$("unique").hide();
}

function noConflict(){
jQuery.noConflict;
}


</script>

<button>JQuery show</button>
<button onclick="javascript:pt();">prototype.js hid</button>
<div id="unique" style="display:none;">Hello,jQuery</div>


위 예제는 JQuery와 Prototype를 같이 사용한 예제 입니다.
서로간의 "$" 충돌을 위해서 jquery사용시에는 "jQuery"
해서 사용하시면 됩니다. 충돌 피하는 방법은
jquery 사이트에서 참고 하시면 될것 같습니다.
지원 라이브러리 와 버전 정보를 알고 싶으면
아래의 사이트에서 확인 하시기 바랍니다.
http://code.google.com/intl/ko-KR/apis/ajaxlibs/documentation/index.html#AjaxLibraries

2010년 2월 7일 일요일

Maven에서 Deploy 하는 방법

Maven에서 Deploy하는 방법 해당 Maven 프로젝트 가있는
경로로 이동해서 "mvn deploy"를 하면 되지만
좀더 고급 스럽게(?) 하려면 아래와 같이 하면 됩니다.

mvn deploy:deploy-file -Dfile=C:/system/beyondj2ee.jar 
-DrepositoryId=beyondj2ee
-Durl=http://localhost:8082/nexus/content/repositories/beyondj2ee-snapshot
-DpomFile=c:/system/pom.xml


-Dfile : Nexus 또는 원격 레파지토리에 deploy할
라이브러리 파일 경로
-DrepositoryId : setting.xml에 원격 레파지토리를 위한
"server" 태그 아이디
예)
    <server>
<id>beyondj2ee</id>
<username>admin</username>
<password>******</password>
</server>
</servers>

-Durl : deploy할 원격 레파지토리 주소
-DpomFile : pom.xml 파일 경로

2009년 9월 30일 수요일

앞으로 전개될 실무 Java Trend

3년전에 제가 처음 스프링 프로젝트를 할때만 해도 실무 프로젝트
에서는 스프링 도입에 대해서 비관적 관망 추세 였습니다.
그러다가 괜찮다는 평이 국내외적으로 나오면서 하나 둘씩 스프링
프로젝트가 생겼고 , 최근에는 거의 필수가 된듯 합니다.
(주위에 개발자분들 부랴부랴 스프링 열공하시고...)
아무리 좋은 오픈소스라도 실무에서 적용하는건 다소 시간이 걸릴
수밖에 없습니다. 이유는 여러가지일수 있지만
그중에서 가장 큰 이유는 아무래도 프로젝트 리스크 때문 일것입니다.
그러니 가끔 열정적인 개발자 분들 중에서
"나온지가 언제인데 지금에서야.."
라는 말보다는 실무적인 환경에 대한 이해를 하셨으면 하는 바램입니다.
스프링뿐만 아니라 오픈 소스가 있어서 정말 쉽게 편하게 개발을
하지만 반면에 너무 많다 보니 언제 이것들을 공부해야 하는
부담감도 있습니다. 오픈소스를 잘쓰는 것도 중요하지만
더 중요한건 어떤 오픈 소스가 앞으로 리딩할지에 대한
선택이 더 중요하다고 생각 합니다. 우리나라 개발 환경상
듣보잡 오픈소스까지 공부하기에는 물리적 시간이
한계가 있습니다.
그래서 앞으로 실무에서 전개될 Java Trend 에 대해서
제 개인적인 생각을 말하고자 합니다.

  • RPC (Remove Procedure Call)
Java에서 RPC는 다양한 형태로 지원 하고 있습니다.
tcp/ip socket,ejb,rmi,spring http invoker,web service
등이 있습니다.
최근에 많이 사용하는 RPC는 아무래도 웹 서비스
겠죠.
하지만 웹 서비스가 만만치 않은 넘입니다.
요샌 알아서 추상화되어 있어서 편리해졌지만
복잡한 스펙,이기종간에 알 수없는 에러들..
(웹 서비스를 해본신 분들은 아실 것입니다.)
그래서 보다 쉽고 편리한 URI 기반의 REST를
점차 사용하는 추세 입니다.
데이터 전송 type은xml대신 JSON을 사용합니다.
즉 "REST+JSON"가 대세가 되지 않을까 생각 합니다.
실제로 "REST+JSON" 형태의 RPC를 실무에서
사용하고 있습니다. (모든 검토후 내린
선택이니 REST를 쓰는 이유가 있겠죠^^)
REST를 구현한 구현체들은 많지만 개인적으로
"Apache CXF"를 추천 합니다.

  • Framework + ORM
일단 Framework은 Spring이 당분간 강세가 될 듯 합니다.
Seam이 나름 ejb2를 보완했긴 했지만 여전히 100%
pojo라고 말하긴 다소 제약 사항이 있습니다.
(pojo in Action을 참고하심)
그래서 Framework은 스프링으로 쭈욱 갈듯 합니다.
ORM은 현재는 "iBatis"가 대세지만
(ibatis를 ORM 범주에 넣는다게 좀.. )
"Hibernate"로 결국에는 갈 듯합니다.
이유는 기술적인 요소보다는 아키텍쳐 측면
입니다. service+dao 패턴에서 도메인 패턴으로
설계를 하려면 하이버네이트는 필수라고 생각합니다.
꼭 하이버네이트말고도 가능하지만 그래도
ORM은 하이버네이트가 대세가 될듯

  • Architecture Method
대부분 프로젝트를 보면 비즈니스 컴포넌트들은
Service,DAO,DTO 클래스를 적당히 메서드를 설계해서
개발 합니다. 솔직히 이건 객체지향 개발 방법이 아니죠
객체지향은 말그대로 속성,행위가 있어야 하는데
실제로는 속성 따로, 메서드 따로 관리를 하고 있습니다.
"pojo in action"에서는 이런 방법을
"procedural code"라고 합니다. 말그대로 절차적 방법
입니다. 이런 방법은 대표적 언어가 "C언어" 입니다.
즉 객체지향 언어로 C언어 방식의 코드를 작성 하는거죠.
왜 이렇게 된이유는 잘못된 ejb 문화 때문이죠
ejb가 객체지향으로 표현하기에는 한계가 있어서
이런 설계를 했는데 마치 이것이 J2EE 기본인양 되어
있다는 거죠.
위와 같은 문제를 하기 위해서 "POJO 기반의 도메인 모델링"
이 필요하며 이런한 것을 구현하기 위해서는 위의
설명처럼 Spring+Hibernate가 필요합니다.


  • Ajax
Ajax는 라이브러리는 jQuery는 필수고 ,Extjs에 대해서는 관심을
가져야 할 듯 합니다. 이유는 많이 사용한다란 것입니다.

정리 하면 CXF,Spring,Hibernate,JQuery이고 추가로
Maven,Spring Batch 정도가 될 듯합니다.

OSGi나 뭐 대단한 트렌드를 기대 했다면 실망 하셨을 것
같지만 위에서 말한것 처럼 실무적 관점이기 때문에
이해를 하셨으면 합니다.
참 트렌드를 말씀드린다는게 개발자 입장에서 상당히
조심스러운 부분입니다.
"저런거 다 필요없어" 하는 개발자분들도 있을 겁니다.
그런분들이 최근에 스프링에 대해서
엄청 열공 하시더라구요 ^^
혼자 스터디 하는 것 보다
대리 ~ 과장들은 기술기반, 과장 ~ 차장은 아키텍쳐 설계
로 나누어서 하면 좋을듯 합니다.

2009년 9월 9일 수요일

JSTL c:forEach 활용 하기 (first, last)

얼마전 컨트롤러에서 저장된 List 객체를 JSP에서
출력을 하려고 했습니다.
JSTL의 "c:forEach"을 이용해서 처리 하려고 했는데
요구 사항이 좀 지저분 했습니다.
마지막 Row만 다른 css의 class를 적용 해야 했습니다.
이런 자잘 하면서 은근 손이 가는건 정말 짜증이 밀려 옵니다.
컨트롤러에서 List를 하나씩 꺼내서 마크를 할까 아니면
그냥 JSP의 스크립트를 사용할까 고민고민 하던중
JSTL의 깜찍한 기능을 발견 하게 되었습니다.
뒷북이지만 만약 모르신분들이 있다면 유용하게 사용 할 것
같아서 포스팅 합니다.

  • 사용 방법
아래와 같이 출력이 되어야 합니다.
"★ spring | Beyond | J2EE"
첫번째 Row에는 "" 찍어야 하고 마지막 Row는 "|"를 생략 해야 합니다.

Controller Side
List list = new ArrayList();
list.add("spring");
list.add("Beyond");
list.add("J2EE");
request.setAttribute("list",list);

Jsp Side


<c:foreach var="resultList" items="${list}" varstatus="status">
<c:if test="${status.first}">

</c:if>
<c:out value="${resultList}">
<c:if test="${!status.last}">
|
</c:if>
</c:out>
</c:foreach>

1 : varStatus 속성을 이용해서 loop시 현재 Row를
참조 할 수 있도록
합니다.
2 ~ 4 : varStatus 속성에 정의된 변수의 상태 값
중에서 "first" 즉
첫번째 Row일 경우에만
실행 합니다.

6 ~ 8 : varStatus 속성에 정의된 변수의 상태 값
중에서 "last"일 경우는 마지막 Row를 실행 하지만
조건을 "Not"을 주었기 때문에 반대인 경우입니다.
,즉 마지막 Row가 아닐경우만 실행 합니다.

이런 기능이 이미 있었는데도 귀찮니즘때문에 찾아 보지
않았던 것 같습니다. 개발하기전에 "혹시 이런 기능이
있지 않을까" 하면서 스펙을 찾아보는 습관이
중요하다는걸 새삼 느낍니다.

2009년 9월 7일 월요일

Spring에서 Junit Test 사용하기 (for junit 3.8)

스프링이 제공 하는 여러 훌륭한 기능이 있습니다.
그중에서 개인적으로 큰 점수를 주는 건 테스트가
용이하다는 것입니다. 애자일 개발 방법론
중에서 테스트 기반 개발 방법은 필수죠.
실제로 스프링을 만든 로드존슨도 애자일 애호가 이기 때문에
어떻게 하면 테스트를 보다 쉽고 편리하게 할수 있을지 고민을
많이 했다고 합니다.

  • Junit 3.8
이 포스트는 junit3.8 기반에 Jnuit 테스트를 진행 하려고 합니다.
왜 하필 최신 버전이 아닌 3.8 버전을 설명 하는 이유는
크게 두가지 정도라고 생각 합니다.

첫째는 현재 개발 플랫폼이 JDK1.4 이하일 경우
,

두번째는 annotation에 대해서 팀원들이 이해가 부족하거나 혹은 이유 없이 그냥 사용하기 싫어서 .

솔직히 두번째 이유는 설득력 떨어지지만
그래도 실무에서는 자주 발생되더군요 ^^.
하지만 첫번째 이유에 대해서는 정말 중요하다고 생각 합니다.
프로젝트 하면서 항상 느끼는건
"개발자는 개발 스펙에 자유로울 수 없다" 입니다.
즉 협업 시스템에서 정해진 개발 스펙을 따라야 한다는 거죠.
항상 최신 스펙만으로 개발을 할 수 없다는 거죠.

  • 스프링에서 Junit 3.8 사용 방법
"Pro Spring"을 보면 3.8 기반에서 junit 사용법을 3가지로 설명 되어
있습니다.

  1. extend TestCase
TestCase 상속 받아서 "ClassPathXmlApplicationContext"
를 리턴하는 private 메서드를 작성해서
테스트 메서드(testXXX로 시작하는 메서드) 실행시 매번
"ApplicationContext"를 가져오는 방식 입니다.


2. extend AbstractSpringContextTests

스프링에서 제공하는 'AbstractSpringContextTests" 추상 클래스를
상속 받아서 "loadContext" 추상 메서드를 구현합니다.
각 테스트 메서드는 부모의 "getContext" 메서드를 호출 함으로써
"ApplicationContext"를 가져오는 방식 입니다.

3. AbstractDependencyInjectionSpringContextTests

스프링에서 제공하는 'AbstractDependencyInjectionSpringContextTests"
상속 받아서 "getConfigLocations()"를 구현 합니다.
두번째 방법과 유사 하지만 이 방법은 bean을 가져올때 별도의
설정 없이 스프링에서 제공하는 injection 방법으로 사용 할 수 있습니다.

  • AbstractDependencyInjectionSpringContextTests
3가지 방법 중에서 세번째를 선택 한 이유는 첫째 매번 테스트 메서드
실행시 context를 로드할 필요 없이 한번만 하면 됩니다.
두번째는 사용하기가 용이 합니다. TestUnit를 스프링 빈처럼
사용 하면 됩니다.

※만약 JUNIT 실행시 XML 파서 에러가 발생 되면
"xml-apis-2.0.2.jar"

다운 받아서 클래스 패스에 추가 하시기 바랍니다.


import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
import com.secl.app.hops.pkm.services.DefaultService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DefaultUserServiceIntegrationTests extends
AbstractDependencyInjectionSpringContextTests {

private Logger logger = LoggerFactory.getLogger(this.getClass());

private DefaultService defaultService;

protected String[] getConfigLocations() {
String[] paths = new String[] {
"classpath:/app/test/context-datasource.xml",
"classpath:/app/test/context-transaction.xml",
"classpath:/app/test/context-query.xml",
"classpath:/app/test/context-user.xml", };
return paths;
}

public void setDefaultService(DefaultService defaultService) {
this.defaultService = defaultService;
}

public void testUnitTest() throws Exception {
logger.info(this.defaultService.junitTest().toString());
assertTrue(true);
}
}

※마치 Controller로 유사한 형태 입니다.
6 : 반드시 클래스를 상속 받아야 합니다.
10,21 ~ 23 : injection할 서비스 와 setter 함수를 선언 합니다.
12 ~ 19 : Spring 빈을 로드할 xml 파일을 선언 합니다.

  • 유의 사항
스프링 bean xml을 설계할때 (junit 3.8,4.x 공통)
단위 테스트를 고려하지 않고 설계할 경우가 있습니다.
이럴 경우 나중에 단위 테스트를 만들려고
할때 상당히 애매한 경우가 발생 합니다.
예를 들어서 database 관련 unit 테스트를 하려고 하는데
같은 xml에 jms나 mvc 관련 빈이 설정되면 context를 로더 할때
쓸모 없는 빈이 로딩 될 경우도 생기며 심지어는 업무 특성상
로딩이 되지 않는 경우도 발생 합니다.
그렇기 때문에 빈 xml 설계할 때는 항상 현 시스템이 단위
테스트 하는데 있어서 문제가 없는지 부터 파악 하시고
빈 xml을 설계 하시길 바랍니다. 특히 database 관련된 것들은
반드시 별도의 xml로 관리 하시길 바랍니다.

2009년 9월 4일 금요일

Agile에 대한 나의 생각

  • Agile란?
얼마전(9/4)에 Agile의 대부 켄트 벡이 한국을 방문해서 세미나를 했습니다.
몇 년전만해도 Agile에 대해서 와 정말 기다려왔던 방법론인데 하면서도
우리나라 실무에는 적합하지 않는다고 생각 했을 것입니다. 하지만
점점더 Agile이 현실로 다가오는 기운을 느끼고 있습니다.
사실 스프링을 만든 로드존슨도 Agile 애호가 입니다.
그러면 과연 Agile은 폭포수 개발방법론 처럼 하나의
개발 방법론 일까요? XP,스크럼,RUP, 린 소프트 같은
방법론을 잘지키면 Agile일 까요?
제가 생각하는 Agile은 문화라고 생각이 듭니다.
아래는 애자일 선문의 일부 입니다.
  1. 프로세스와 도구보다는 상호작용과 개인
  2. 포괄적 문서와 보다는 동작하는 소프트웨어
  3. 계약 협상 보다는 고객과의 협력
  4. 계획 준수 보다는 변화에 대화에 대한 응대
(엔터프라이즈급 애자일 방법론 중에서..)

만약 우리의 개발팀이 이런한 철학 과 문화를 기반으로
우리만의 개발 방법론을 만들면 바로 그것이
애자일 방법론이라 생각합니다.
  • Agile에 대한 준비
현실로 들어와서 과연 우리 팀은 Agile을 할 준비가
되었있는지 생각해 봐야 합니다.
XP,스크럼 어쩌고 저쩌고 떠들면서 서로
커뮤니케이션이 잘되는지 대리급은
윗 사람들 고리타분 하다고 하고 과장급이상은
너희가 실무를 알어 그런거 필요없다며
낡은 경험을 무기로 무시하지 않는지.
서로 인정하지 않는 분위기에서 Agile을
하느니 화기애애한 분위기에서 폭포수
개발 방법이 생산성이 더뛰어날수도
있습니다.
실제 있었던 내용입니다.
한번은 "야 내일 부터 스탠드업 미팅 하자" 하고
팀장이 말했습니다.
다음날
팀장 : "그래 팀원A부터 말해봐"
팀원A: "어제 관리자쪽 모듈 했구요. 나머지는 이번주 까지 해야 할 것 같습니다."
팀장: "음.. 수요일까지 끝내도록해"
팀원A:".."
이건 완전 주간보고도 짱나는데 일일 보고로 되어 버렸습니다.
이해를 못한건지 Agile을 악용하는건지.
제발 XP가 말이야 어쩌고 보다 우리 팀이 정말
Agile 집단이 되도록 정비했으면 합니다.

  • Agile리더 그룹
만약 Agile을 프로젝트에 적용하기로 한다면 아무래도
일반 개발 업체보다는 "을"업체에서 아무래도 리더를
할 것입니다.
그런데 때로는 Agile을 잘못 이해를 하는 경우가 있습니다.
실무에서 적용한다면 정규직이 전체인 개발팀인경우는
팀내에서 천천히 호흡을 맞출수 있지만 실제로는
SI 같은경우는 50%가 프리랜서일 경우가 많을
것입니다. 그러다보니 Agile 개발 방법에 대해서
다소 적응기가 필요할 것입니다. 그런부분을
고려가 되어 있어야 할것 같습니다. 그리고
왜하는지에 대해서도 그렇지 않으면 반감만
생길 것입니다. 그리고 일정이나 전제적인
분위기는 폭포수면서 무늬만 Agile 경우는
안하느니만 못한다고 생각합니다.
---------------------------------------------------------------------
Agile 리더 : "TDD는 기본이지 JUNIT 테스트까지 해야 한본으로 인정합니다."
개발자들 : "아 개발시간도 촉박한데 무슨 JUNIT이야 . 그냥 클래스 만들고 assert(true)
해야지"
---------------------------------------------------------------------

---------------------------------------------------------------------
Agile 리더 : "생각보다 일정이 늦네"
개발자들 : "개발도 해야 하고 junit도 만들어야 하고"
Agile 리더 : "시간 없으니 일단 구현부터 하고 junit 일괄로 만드세요"
---------------------------------------------------------------------

junit 테스트 결과 다 성공으로 나왔는데도 불구하고 오류 사항이
발생 합니다. 이유인즉은 당연히 junit 테스트 코드를 개발자가 작성하고
자기위주로 assert 조건을 주니 통과가 되겠죠

지금까지 제가 애기 하고 싶은건 저역시 눈물 나게 Agile을 하고 싶은
사람중 한사람입니다. XP,스크럼 모 상관없음...
하지만 현실과 차이가 좀있는것 같습니다.

2009년 8월 20일 목요일

프로젝트에 유용한 Eclipse Plugin 소개

프로젝트를 하다보면 설계/개발도 중요하지만 툴 또한 요샌 무시
할수 없죠. 그 중에서 이클립스 플러그인을 소개하고자 합니다.
이클립스를 사용하는 이유중 큰 부분을 차지하고 있는 것은
바로 plugin일 것 입니다. 그중에서 몇몇 유용한 플러그인은
반복적인 노가다를 줄이고 개발 생산성에
큰 도움이 됩니다.
제가 개인적으로 사용하는 플러그인 과 새로 발견된 유용한
플러그인을 소개하고자 합니다.
참고로 Eclipse 3.5에서 테스트 했습니다.
  • ibator
국내에서 제일 많이 사용하는 Sql 맵퍼로는 당연 iBatis
일 것입니다.
iBatis는 맵퍼로써 매우 유용하지만, 이걸 사용하기 위해서는
Value Object,SqlMap.xml,DAO를 단순 반복을 통해서 생성해야 하는
귀차니즘이 있습니다. 이러한 리소스들의 코드를 생성하는
플러그인 입니다.
개인적으로 제일 마음에 드는건 "테이블 to ValueObject"
기능입니다.
예를들어서 테이블에 MEMBER_ID 컬럼이 있으면 VO객체의
속성은 memberId로 맵핑 됩니다.

(1) 설치 (이클립스 플러그인 추가 방법은 생략 하겠습니다.)

아래의 주소로 이클립스 플러그인 업데이트를 실행 합니다.
http://ibatis.apache.org/tools/ibator
※ 설치시 반드시 이클립스 버전에 맞게 설치 하세요.
3.4 이상인 경우 3.x가 있는 리스트를 체크하시고
설치 하시기 바랍니다.

(2) 실행

프로젝트의 특정 디렉토리에 "abatorConfig.xml"를 생성 합니다.
파일을 오픈해서 코드를 작성합니다. 작성 완료 후
해당 파일을 선택하고 오른쪽 클릭을 합니다.
박쥐모양 같은 의 아이콘 "Generate iBATIS Artifacts"를 실행 하시면
됩니다. Junit 실행과 흡사 합니다.



HomePage : http://ibatis.apache.org/ibator.html
Menual Site : http://ibatis.apache.org/docs/tools/ibator/

  • GotoFile (3.5 지원 안함)
이 플러그인은 파일을 검색해주는 플러그인 입니다.
이클립스의 단축기 "Shift+Ctrl+R" 와 같은 기능을 하지만
더욱더 보완된 기능을 갖고 있습니다. 예를 들어서 검색어를
입력하면 마치 네이버 검색창 처럼 현재 입력 키워드에 대해서
파일을 검색합니다. 참고로 키워드는 파일명을 검색하지
파일내에 내용을 검색하지는 않습니다.

(1) 설치

아래의 주소로 이클립스 플러그인 업데이트를 실행 합니다.
http://www.muermann.org/gotofile/update

(2) 실행

설치 후 이클립스 재시작 하면 왼쪽 상단에 "Quick Search"
버튼이 생성 되며 , 해당 아이콘을 클릭 후 검색 창에 키워드를
입력 하면 됩니다.


HomePage : http://www.muermann.org/gotofile

  • JAutoDoc
개인적으로 보물과 같은 플러그인 입니다. 심플하면서 강력한 플러그인 이죠.
이름에서 볼수 있듯이 메서드,생성자등 소스에 선언된 모든 것에
대해서 javadoc를 자동 생성해 줍니다.
구글에 검색하면 관련 포스트많이 보실 수 있습니다.

(1) 설치

아래의 주소로 이클립스 플러그인 업데이트를 실행 합니다.
http://jautodoc.sourceforge.net/update/


(2) 실행

javadoc를 생성할 소스를 오픈 합니다. 해당 편집기에 "Ctrl+Alt+J"를
실행하면 현재 소스에 주석을 자동 생성해 줍니다.
이클립스에서 제공하는 기능이 있지만 메서드 변경시
변경 사항을 반영을 못하는 단점이 있습니다.
이클립스이 code template 과 autodoc를 사용하면
javadoc 작성으로 부터 많이 해방될듯 합니다.
"Preference"-"java"-"JAutodoc" 에서 플젝에
맞게 수정 하시면 됩니다.

HomePage : http://jautodoc.sourceforge.net/

  • Properties Editor
properties 파일은 메세지,환경 설정 파일로 많이 사용하고 있는데
properties 파일 특성상 유티코드 인코딩 문제로 한글이 깨져
나옵니다. "native2ascii " 을 사용해서 변환을 하면 되지만
매번 개발하면서 실행한다는 것입니다.
이런 불편함 없이 자동으로 변환할수 있는에디터 입니다.
개발자는 별다른 설정 없이 메모장 쓰듯이 사용하면
내부적으로 자동으로 변환 해줍니다.


(1) 설치

아래의 주소로 이클립스 플러그인 업데이트를 실행 합니다.
http://propedit.sourceforge.jp/eclipse/updates/

(2) 실행

이클립스 재실행 후 .properties 파일을 선택 후 "오른쪽 클릭" -
"Open With" - "Properties Editor" 열어서 메세지를 작성하면
됩니다.

HomePage : http://propedit.sourceforge.jp/index_en.html
  • jora (3.5 지원하지 않음)
제가 두번째로 가장 좋아하는 플러그인 입니다. 오라클 전용 개발
플러그인 입니다. 모랄까 toad 와 golden 합쳐놓았다고 생각 하시면
됩니다. 그리고 tns 연결 뿐만 아니라 jdbc로도 접속이 가능해서
오라클 클라이언트 설치가 필요가 없습니다. 개인적으로
큰 점수를 줄수 있는건 golden 처럼 ";"로 쿼리를 구분해서
쿼리를 질의 할수 있고 단축키("Ctrl+Enter")로 실행 할 수 있습니다.
단순 쿼리 부터,스키마 뷰,PL/SQL 에디터,세션정보등
Admin 기능도 제공 합니다.

(1) 설치

아래의 주소로 이클립스 플러그인 업데이트를 실행 합니다.
http://jora.luenasoft.de/updatesite

(2) 실행

jOra는 별도의 "Perspective" 창을 제공 합니다.
"Window" - "Open Perspective" - "Other" -"jOra DB"
선택하시면 jOra 전용 Perspective 창이 생성 됩니다.
왼쪽 상단에 "New Connect" 버튼을 클릭해서
접속 하시면 됩니다.
"Java Perspective" 창으로 전환해도 "SQL WorkSheet" 가
닫히지 않기 때문에 JAVA 코딩하다가 바로 쿼리를 질의
할 수 있습니다.
UI가 익숙하기 때문에 사용법은 금방 익힐수가 있습니다.



http://jora.luenasoft.de/features.html
  • Eclipse Wiki
스프링 프로젝트를 진행 하다보면 많은 메타 파일 및 소스 파일이 있습니다.
특히 메타 파일(XML) 을 추가 및 수정 하고자 할때
이클립스 프로젝트 구조에서 찾아 다니는건
은근 피곤한 일입니다. 스프링 XML 같은 경우는 그나마
Spring IDE에서 한 곳으로 모아주는 기능이 있어서 낫지만
SQL,설정 파일 ..등은 그렇지 않습니다.
Eclipse Wiki이 이런한 불편을 간편하게 하기 위해서
.wiki라는 파일을 생성하고 거기서 파일들을 링크설정을
합니다. 그리고 해당 설정부분에 "F3" 버튼을 누르면
설정된 페이지가 열립니다. 즉 메타 파일을 하나의 파일로
중앙집중적으로 관리 할 수 있는 플러그인 입니다.

(1) 설치

아래의 주소로 이클립스 플러그인 업데이트를 실행 합니다.
http://www.stateofflow.com/UpdateSite
※ 업데이트시 반드시 "Eclipse Wiki" 만 체크하고 설치 하시기 바랍니다.

(2) 실행

이클립스 재실행 후 "Window" - "Customize Perspective"
- "commands" - "Available command groups' -
"Eclipse Wiki" 체크 후 - "OK"

프로젝트 특정 위치에 XXX.wiki 라고 파일을 생성 합니다.
여기서 파일명은 사용자 마음이지만 확장명은 반드시 .wiki로 선언해야 합니다.
파일을 열때 "Open With" - "Wiki Editor"로 열어야 합니다.
해당 페이지로 이동할 링크에 커서를 놓고 "F3"을 누르면 해당 페이지가
열립니다. http,ftp,mailto 지원합니다. 자세한 사항은 이클립스
"Help"에서 키워드를 "Eclipse Wiki"로 검색해서 도움말을
참고 하시면 됩니다.

  • Log4E
개발에서 있어서 로그는 필수 사항이죠. Log4E는 로그 코드를
자동 생성해 줍니다. 예를 들어서 로그를 찍기 위해서는
"if(logger.isDebug) {logger.debug("--")}" 라는 코드를
클래스,또는 메서드 특정위치에 커서롤 놓고 실행하면
위의 코드가 소스안으로 삽입 됩니다.

(1) 설치

아래의 주소로 이클립스 플러그인 업데이트를 실행 합니다.
http://log4e.jayefem.de/update
※ 3.x 버전만 체크 후 설치해야 합니다.


(2) 실행



HomePage : http://log4e.jayefem.de/

  • Subversive

"subclipse" 와 비슷합니다. 하지만 다양한 관리 UI를 제공합니다.
둘 중에서 어떤게 나은지 의견이 분분합니다. 개인적으로는 별 차이가
없어서 기왕이면 Subversive를 사용하고 있습니다.

(1) 설치

아래의 주소로 이클립스 플러그인 업데이트를 실행 합니다.
http://www.polarion.org/projects/subversive/download/integrations/update-site/

HomePage : http://community.polarion.com/index.php?page=overview&project=subversive

※"3.5 지원하지 않음" 에 대한 근거는 지극히 주관적 판단입니다.
제가 Eclipse 3.5에서 테스트시 설치가 안된 경우 입니다.
제가 실수를 할 수도 있고, 아직 플러그인 자체에서
3.5를 지원 못 할수도 있습니다. 즉, 위의 플러그인들이 설치가 안되더라도
항상 예의 주시해서 꼭 적용해보시기 바랍니다. 그리고 추천 플러그인이나
또는 설치시 문의 사항은 댓글을 남겨 주시기 바랍니다.

2009년 8월 19일 수요일

스프링 최고의 IDE SpringSource Tool Suite로 갈아 타자

최근에 SpringSource에서 이클립스 3.5 기반에 스프링 IDE인
"SpringsourceTool Suite"를 릴리즈 했습니다.
3.4 버전에서 zip파일 다운받아서 설치 하는게 아니라.
일반 윈도우 프로그램처럼 다운 받아서 단계별로 설치하기 때문에
쉽고 간단하게 변경 되었습니다.
센스 있게 WTP,Maven,Mylin 등 기본적인 플러그인도
설치가 되어있습니다.
STS의 기능은 스프링빈 XML 설정 및 validate 검사 ,
Webflow,Batch 개발시 그래픽한 UI,
DM 서버 및 TC 서버 지원등 스프링 개발에 있어서
최고의 IDE 툴이라 할 수있습니다.
자세한 기능은 아래 사이트를 참고 하시기 바랍니다.
STS : http://www.springsource.com/products/sts
TC Server : http://www.springsource.com/products/tcserver

  • STS 다운로드
다운로드 사이트를 접속 합니다. 기본 사항을 작성하고
"Download Now" 버튼을 클릭 합니다.

이클립스 3.5 버전의 STS를 다운 로드 합니다.

  • 설치 하기





STS를 제외한 부분은 용량이 많지 않으므로 전체 설치를 합니다.


JDK 경로를 설정후 계속 진행 합니다


(지루한 INSTALL ㅠ.ㅠ)



설치가 완료 되면 "프로그램"-"SpringSouce"를 실행 합니다.


헋 이포스는 !



앞으로 스프링 개발을 하기 위해서는 STS는 필수 사항이 될 것같습니다.
추후에 사용기를 또 올리도록 하겠습니다.

2009년 7월 27일 월요일

Java 객체 복사(Clone) Best Practice

effective java 2nd를 보면 자바 객체 복사(Clone)하는 방법에 대해서 자세하게 기술되어 있습니다.
객체를 복사하려면 복사하려는 객체에 Cloneable 인터페이스를 implement 하고 Object 객체의
clone 메서드를 override 해야 합니다. 하지만 단일 클래스일 경우는 괜찮지만
슈퍼 클래스-자식 클래스 와 같이 상속 구조의 클래스 형태는 고려해야 할 사항이
많습니다. 심지어는 복사의 기술적 매커니즘은 자바 기술 밖이라고 합니다.
왜그런지는 설명하기도 어렵고 이해하기도 어렵습니다. 즉 복사를 하려고 했을때
고려해야 할 사항이 너무 많습니다.

그래서 추천하는 복사 방법은 "copy construction" 이란 방법 입니다.
책에는 예제가 없어서 제가 외국 사이트에서 소스 얻어서 재구성 했습니다.

Super Class



import java.util.ArrayList;
import java.util.List;

public class Dog {
private final List names;
private int age;
private int weight;
private String str;
private String values[] = new String[2];

public Dog() {
names = new ArrayList();
}

protected Dog(Dog original) {
names = new ArrayList(original.names);
age = original.age;
weight = original.weight;
str = original.str;
System.arraycopy(original.values, 0, values, 0, original.values.length);
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public int getWeight() {
return weight;
}

public void setWeight(int weight) {
this.weight = weight;
}

public String getStr() {
return str;
}

public void setStr(String str) {
this.str = str;
}

public String[] getValues() {
return values;
}

public void setValues(String[] values) {
this.values = values;
}

public List getNames() {
return names;
}

public Dog copy() {
return new Dog(this);
}

}


Child Class


public class Dalmatian extends Dog {

private int spots;

public Dalmatian() {
}

protected Dalmatian(Dalmatian original) {
super(original);
spots = original.spots;
}

public Dalmatian copy() {
return new Dalmatian(this);
}

public static void main(String[] ar) throws Exception {

Dalmatian dalmatian1;
Dalmatian dalmatian2;
String temp;

// 복사 source 클래스 셋팅
dalmatian1 = new Dalmatian();
dalmatian1.setAge(1);
dalmatian1.setStr("00000");
dalmatian1.getNames().add("xxxxx");
dalmatian1.getNames().add("yyyyy");
dalmatian1.getValues()[0] = "----------------";

// target 클래스 복사
dalmatian2 = dalmatian1.copy();

// 복사된 내용 확인 하기
System.out.println("= copy description =========");
System.out.println("copy age ==&gt; " + dalmatian2.getAge());
System.out.println("copy str ==&gt; " + dalmatian2.getStr());
System.out.println("copy names ");

for (int i = 0; i &lt; dalmatian1.getNames().size(); i++) {
temp = (String) dalmatian1.getNames().get(i);
System.out.println(temp);
}
System.out.println("copy values == ");
System.out.println(dalmatian1.getValues()[0]);

System.out.println("= copy description =========");
System.out.println();

// 값은 메모리 주소를 사용하는지 값 과 hashcode 비교
System.out.println("= change value =========");
dalmatian2.setAge(2);
System.out.println("=age1 ==&gt; " + dalmatian1.getAge());
System.out.println("=age2 ==&gt; " + dalmatian2.getAge());
System.out.println();

dalmatian2.setStr("11111");
System.out.println("=str1 ==&gt; " + dalmatian1.getStr());
System.out.println("=str2 ==&gt; " + dalmatian2.getStr());
System.out.println("=str1 hc ==&gt; " + dalmatian1.getStr().hashCode());
System.out.println("=str2 hc ==&gt; " + dalmatian2.getStr().hashCode());
System.out.println();

dalmatian2.getNames().add("wwwww");
dalmatian2.getNames().add("zzzzz");
System.out.println("=names1 ");

for (int i = 0; i &lt; dalmatian1.getNames().size(); i++) {
temp = (String) dalmatian1.getNames().get(i);
System.out.println(temp);
}
System.out.println("=names2 ");
for (int i = 0; i &lt; dalmatian2.getNames().size(); i++) {
temp = (String) dalmatian2.getNames().get(i);
System.out.println(temp);
}
System.out.println("=names1 hc ==&gt; " + dalmatian1.getStr().hashCode());
System.out.println("=names2 hc ==&gt; " + dalmatian2.getStr().hashCode());
System.out.println();

dalmatian2.getValues()[0] = "====================";

System.out.println("=value1[0] ==&gt; " + dalmatian1.getValues()[0]);
System.out.println("=value2[0] ==&gt; " + dalmatian2.getValues()[0]);
System.out.println("=value1 hc ==&gt; "
+ dalmatian1.getValues().hashCode());
System.out.println("=value2 hc ==&gt; "
+ dalmatian2.getValues().hashCode());
System.out.println("= change value =========");

}
}


== Result OUT ==

= copy description =========
copy age ==> 1
copy str ==> 00000
copy names
xxxxx
yyyyy
copy values ==
----------------
= copy description =========

= change value =========
=age1 ==> 1
=age2 ==> 2

=str1 ==> 00000
=str2 ==> 11111
=str1 hc ==> 45806640
=str2 hc ==> 46760945

=names1
xxxxx
yyyyy
=names2
xxxxx
yyyyy
wwwww
zzzzz
=names1 hc ==> 45806640
=names2 hc ==> 46760945

=value1[0] ==> ----------------
=value2[0] ==> ====================
=value1 hc ==> 7699183
=value2 hc ==> 14285251
= change value =========

소스가 좀 기네요 public static void main 함수는 분석 하시지 마세요. ^^ 바로 Resut OUT을 보시면서 이해
하시면 될 것 같습니다.
여기서 중요한 건 슈퍼 클래스 생성자 함수 인데 배열은 값 복사가 메모리 주소 참조값을 그대로 복사하기
때 문에 반드시 "System.arraycopy(original.values, 0, values, 0, original.values.length);" 사용해서
deep copy를 해야 합니다.
객체 복사는 prototype 디자인 패턴에서도 사용하며, 실제 개발을 하다 보면 clone이 필요한 경우가
있습니다. 참고 하시기 바랍니다.