효율적인 테스터의 7가지 습관

효율적인 테스터의 7가지 습관
(The Seven Habits of Highly Effective Testers)

원문 URL (URL of the original article): http://www.qaguild.com/weekly_article.php?id=35

이 글은 글의 원 저자인 Steve Miller의 구두 허락 하에 한국어로 번역되고, 개인 블로그에 포스팅되었습니다.
This article has been translated into Korean language with the permission of the original auther, Steve Miller.

Stephen R. Covey가 1989년에 쓴 성공하는 사람들의 7가지 습관이라는 책이 있습니다. 이 책은 수백만명의
사람들이 일과 인생의 효율성에 있어서 진정한 상호 의존성(interdependent effectiveness)을 성취하는데 많은
도움을 주었습니다. 이 글을 통해 효율적인 테스터가 취할 수 있는 7가지 좋은 습관에 대해 제시하고자 합니다. 이 7가지 습관을
요약하자면 다음과 같습니다.

  1. 적극적인 자세를 가질 것 (Be proactive)
  2. 끝을 염두에 두고 시작할 것 (Begin with the end in mind)
  3. 기본적인 것들을 먼저 시작할 것 (Put first things first)
  4. 윈/윈 전략을 취할 것 (Think Win/Win)
  5. 이해받으려 하기 보다 먼저 이해하십시오. (Seek First to Understand, Then to be Understood)
  6. 시너지를 낼 것 (Synergize)
  7. 날을 날카롭게 할 것 (Sharpen the Saw)

습관 1 – 적극적인 자세를 가질 것 (Be proactive)

떤 소프트웨어 프로젝트에 있어서든, 테스터의 목표는 소프트웨어가 높은 수준의 품질로 릴리즈되는 것입니다. 소프트웨어 프로젝트가
낮은 품질로 인해서 실패한다면, 그 요인이 무엇인지 분석을 해야 합니다. 이 때 테스터는 적극적으로 분석을 할 수도 있지만
소극적인 자세를 취할 수도 있습니다. 만약 소극적인 자세를 취한다면 아마도 비난할 다른 사람 또는 그렇게 될 수밖에 없었던
상황과 환경을 찾을 것입니다. 반대로 적극적인 자세를 취한다면 우선 그 실패에 대한 책임을 지고 미래의 프로젝트들에서 그 문제가
재발하지 않도록 하기 위한 방법을 찾을 것입니다.
모든 프로젝트는 종료 시점에 “포스트 모텀 (Post mortem)”
또는 “Retrospective”를 수행함으로서 그 프로젝트에서 무엇이 성공적으로 이루어졌고 무엇이 많이 부족했었는지를
공개적으로 토론합니다. 미래의 프로젝트에 있어서 적극적인 자세를 취할 수 있는 몇가지 아이디어를 제시합니다.

1.
소프트웨어 요구사항에 대해 책임감을 가지십시오. – 빈약한 요구사항 정의와 관련하여 다른 사람을 비난하지 마십시오. 대신 관련
팀과 함께 요구사항 정의가 완벽하게, 정확하게, 그리고 테스트 가능하게 작성되었는지 적극적으로 확인하십시오.
2. 추적성을
확보하십시오. – 테스트 케이스를 작성할 때 어떤 요구사항에 대해 어떤 테스트 케이스가 만들어졌는지 추적할 수 있는 매트릭스를
만들면 테스트 케이스의 커버리지, 테스트 적합성 (testability), 완전성을 분석하는데 많은 도움이 됩니다. 테스트
케이스 작성자가 요구사항을 정확하게 이해했는지 그리고 작성된 테스트 케이스가 적절한 커버리지를 갖는지 리뷰하기 위해 적극적으로
팀 미팅을 주최해야 합니다.
3. 효율적으로 커뮤니케이션 하십시오. – 테스팅 기간 동안 프로젝트 구성원 모두가 테스트
작업의 진행 상황을 공유해야 하는 것은 매우 중요합니다. Email이나 포럼을 통해 매일 매일의 테스트 진행 상황을
공유하십시오. 결함 건수, 요구사항 커버리지, 수행된 테스트 케이스 건 수, Passed/Failed된 테스트 케이스 건 수 등
사용 가능한 다양한 메트릭(Metrics)을 사용하십시오.
4. 발견한 결함을 효율적으로 설명하십시오. – 결함을 설명할
때는 결함 재현 절차와 예상 결과 등을 포함하여 훌륭한 결함 설명을 작성하기 위해 공을 들여야 합니다. 스크린샷이나 기타 사용
가능한 정보는 모두 사용하여 결함에 대해 설명하십시오. 이를 잘 지키면 QA와 관련된 재작업을 최소화할 수 있습니다.


습관 2 – 끝을 염두에 두고 시작할 것 (Begin with the end in mind)

프트웨어 프로젝트와 관련하여 여러분의 최종 목표는 고객의 요구를 만족하는 좋은 품질의 소프트웨어를 제공하는 것일 것입니다.
코딩이 시작되기 전에 반드시 이 프로젝트가 성공했다고 결정할 수 있는 결정 기준 (success criteria)을 만들어야
합니다. 예를 들어, 다음과 같은 기준을 설정할 수 있습니다. – 소프트웨어가 특정 결과물을 생성해내는가, 알려진 결함이
해결되었는가(또는 소수의 중요도 낮은 결함은 허용), 문서화가 잘 되었는가, 사용하기 쉬운가, 기타 등등. 초기 단계에 결정
기준을 설정함으로서 프로젝트 진행 도중에 수시로 프로젝트가 성공적으로 수행되고 있는지 검토할 수 있습니다. 결정 기준을 정의할
때에는 모든 팀 멤버 (PM, 테스터, 자동화 엔지니어, 개발자, 문서화 전문가 등)로 부터 도움을 구하십시오. 개인이 아닌
팀으로서의 시각으로 성공 결정 기준을 확립한다면 더 훌륭하고 많은 정량적인 기준을 확보할 수 있을 것입니다.

습관 3 – 기본적인 것들을 먼저 시작할 것 (Put first things first)

양한 작업들에 대해 우선순위를 부여하는 것은 매우 중요합니다. 일을 할 때는 가장 중요한 작업부터 시작해서 덜 중요한 작업들로
진행해야 합니다. 예를 들어, 네거티브 테스팅(Negative Testing)이 일반적인 소프트웨어 사용자의 사용 패턴이 아닌
특수한 사용 시나리오의 경우에 대해 … 한다는 것은 모두가 동의하고 인정합니다. 그러나 포지티브 테스팅(Positive
Testing)과 비교해봤을 때 네거티브 테스팅은 훨씬 덜 중요합니다.따라서 테스트를 시작할 때에는 미리 설계된 시나리오대로 잘
동작하는지에 대한 테스트를 먼저 시작하고, 또 이러한 테스트를 더 집중적으로 수행하십시오. 이 작업이 완료된 후에 네거티브
테스팅을 진행하는 것이 좋습니다. (경계 테스팅, 부적절 데이터 입력, 오버플로우, 인젝션 등)

습관 4 – 윈/윈 전략을 취할 것 (Think Win/Win)

은 조직에서 개발팀과 테스팅팀은 서로간에 비난하고 책임 소재를 돌리면서 팀간의 긴장감을 조성한다. 이는 상당히 파괴적이며
소프트웨어의 품질과 UX(User Experience)에 좋지 않은 영향을 미칠 수 있다. 개발팀과 테스팅팀은 공동의 목표를
가져야 한다. (고객이 최상의 품질의 소프트웨어를 가질 수 있게 하는 것) 이것이 공동의 목표가 될 때 모든 팀 멤버는 서로를
도울 수 있는 마인드를 가질 수 있게 되고 결국 훌륭한 품질의 소프트웨어가 완성되어 고객도 행복해지고 그로 인해 팀 멤버들도
성취감을 얻을 수 있다. 상호 신뢰의 분위기를 조성하고자 한다면 윈/윈할 수 있는 팀을 육성해야 한다. 이에 대한 몇가지 팁이
있다.

1. 지식 공유 – 여러분의 지식을 혼자 갖고 있지 말고 다른 사람들과 적극적으로 나누십시오.
2. 소셜라이즈(Socialize)하십시오 – 회사의 다른 팀 멤버들과 함께 점심 식사를 하십시오. 그들에 대해 더 배우고, 그들의 취미나 개인적인 목표 등에 대해 관심을 가지십시오.
3.
다른 사람들을 격려하십시오 – 타인이 훌륭하게 업무를 해내었다면 그 사람을 칭찬하고 격려하는데 인색하지 마십시오. 여러분의
(또는 그 사람의) 조직장에게 그 사람이 얼마나 잘 하고 있는지 말하십시오. 그 사람의 노력에 대해 얼마나 감사해하고 있는지
말하십시오.
4. 바쁜 팀 멤버들에게 도움을 주십시오 – 업무로 인해 많이 바쁜 팀 멤버들을 보면 그 일에 함께 뛰어
들어서 도움을 주십시오. 아마도 여러분이 나중에 도움이 필요할 때가 있을 것이므로 도움을 배푸는 것은 윈/윈 관계를
만들어나가는데 큰 도움이 됩니다.

습관 5 – 이해받으려 하기 보다 먼저 이해하십시오. (Seek First to Understand, Then to be Understood)

리 대부분은 우리 의견이 전달되기를 너무나 원하는 나머지 대화를 끊어버리고 상대방으로 부터 들으려하지 않는 아주 나쁜 습관을
갖고 있습니다. 모든 테스터와 팀 멤버는 서로 다른 다양한 경험과 시야(perspectives), 동기(motivations)를
갖고 있습니다. 어떤 문제를 해결하기 이전에 해결해야 할 문제를 완벽하게 이해하기 위해서 주의깊고 적극적으로 듣는 자세가
필요합니다. 모든 사실(facts)을 충분히 갖게 되었다고 느끼면 다양한 해결 방법을 생각해내십시오. 선택 가능한 몇가지 옵션을
가져감으로서 다양한 상황에서 여러가지 대안을 생각할 수 있고 더 낳은 협의를 할 수 있습니다. 만약 어떤 접근법에 대해 동의하지
않는다면 그 접근법을 제안한 사람을 공격하지 마십시오. 대신 여러분의 과거 경험에 기반해서 왜 더 낳은 접근법이 존재할 수
있는지 설명하십시오.

습관 6 – 시너지를 내십시오 (Synergize)
팀의 시너지를 발휘하는데 있어서 가장 중요한 것은 팀 협업입니다. 시너지를 낼 수 있는 팀은 서로 다른 능력과 서로 다른
백그라운드와 서로 다른 시야를 가진 다양한 멤버들로 구성됩니다. 이런 다양성 가운데서 최대한의 시너지를 내려면 도구의 사용이
중요합니다. 고도로 협업적인 (Highly Collaborative) 팀은 그들의 달력 (스케줄)를 공유하고 각 구성원의 현
상황을 적극적으로 포럼에 올려서 모두가 다른 사람들이 지금 무엇을 하고 있고 무엇을 성취하고 있는지 알게 하는 것으로서
커뮤니케이션합니다. 이런 팀은 각 구성원이 각 날짜마다 수행한 작업들과 업무를 수행한 시간, 그리고 어떤 작업을 수행하기까지
계획되었던 시간에 대해 남은 시간 등을 기록합니다. 또한 이러한 팀에서는 각 구성원들이 업무를 수행하면서 배우게 된 것들을
최대한 잘 설명할 수 있는 문서를 생산해내고 이를 공유합니다.

습관 7 – 날을 날카롭게 할 것 (Sharpen the Saw)
생산적인 테스터들은 계속해서 테스팅 기술들을 연마하고 새로운 기술과 베스트 프랙티스와 다양한 접근법들을 배우는 것을 좋아합니다.
그들은 지식에 대한 목마름을 갖고 가능한 모든 테스팅에 대한 책들을 읽습니다. 그들은 자신들의 업무를 쉽게 할 수 있는 방법을
배웁니다. (테스트 케이스를 자동화하고, 베스트 프랙티스를 적용함으로서 QA타임을 최소화하는 한편 소프트웨어 품질을 최대화함.)
이들은 QA Guild나 Sticky Minds 또는 다른 테스팅 커뮤니티에 계속적으로 참여합니다. 그러나 역시 이들은 언제
인생을 즐길지도 압니다. 훌륭한 휴가나 좋은 취미나 활동을 함으로서 방전된 배터리를 충전합니다.

저자에 대하여 (About the author)
Steve Miller는 Pragmatic Software의 사장이자 CEO이며 회사의 전략적 목표를 설정하고 이끌어가는 역할을
수행합니다. Pragmatic Software의 주력 제품은 소프트웨어 개발 생명 주기의 모든 phase를 관리할 수 있는
어플리케이션 라이프사이클 매지니먼트 (ALM) 도구인 Software Planner입니다.

실용주의 개발 환경 목록

웹에 상당히 많이 돌아다니는 링크 목록인데.. 작성한 사람이 누구인지는 모르겠다..


개인용으로 쓰기 위해 일단 내 블로그에 갈무리..^^




  1. 개발 도구

    1. Eclipse : http://www.eclipse.org/
    2. Netbean : http://www.netbeans.org/community/releases/60/index.html
    3. Firebug : http://www.getfirebug.com/

  2. 소스코드 관리

    1. CVS : http://www.cvshome.org
    2. Subversion : http://subversion.tigris.org
    3. MS Visual SourceSafe
    4. BitKeeper : http://www.bitkeeper.com
    5. ClearCase : http://www-306.ibm.com/software/awdtools/clearcase/

  3. 빌드 스크립트 도구

    1. make : http://source.redhat.com/cygwin
    2. Automake : http://www.gnu.org/software/automake
    3. Ant : http://ant.apache.org
    4. NAnt : http://nant.sourceforge.net
    5. Groovy : http://groovy.codehaus.org
    6. Rake : http://rake.rubyforge.org/
    7. SCons : http://www.scons.org/

  4. 빌드 시스템

    1. Maven : http://maven.apache.org
    2. Maven2 : http://maven.apache.org/maven2/index.html

  5. CI 도구

    1. CruiseControl : http://cruisecontrol.sourceforge.net
    2. CruiseControl .NET : http://sourceforge.net/projects/ccnet
    3. DamageControl : http://damagecontrol.codehaus.org
    4. AntHill : http://www.urbancode.com/projects/anthill
    5. Continuum : http://maven.apache.org/continuum
    6. LuntBuild : http://luntbuild.javaforge.com/
    7. Buildix : http://buildix.thoughtworks.com/

  6. 이슈 추적 도구

    1. Bugzilla : http://www.bugzilla.org
    2. JIRA : http://www.atlassian.com/software/jira/default.jsp
    3. FogBugz : http://www.fogcreek.com/FogBugz
    4. PR-Tracker : http://www.prtracker.com
    5. Trac : http://trac.edgewall.org/

  7. 테스트프레임워크

    1. JUnit : http://www.junit.org
    2. NUnit : http://www.nunit.org
    3. xUnit.NET : http://www.codeplex.com/xunit
    4. MbUnit : http://www.mbunit.org
    5. HTMLUnit : http://htmlunit.sourceforge.net
    6. HTTPUnit : http://httpunit.sourceforge.net
    7. JWebUnit : http://jwebunit.sourceforge.net
    8. Cobertura : http://cobertura.sourceforge.net
    9. Clover : http://www.cenqua.com/clover
    10. Cactus : http://jakarta.apache.org/cactus/
    11. Emma : http://emma.sourceforge.net/
    12. Fit : http://fit.c2.com
    13. Fitness : http://fitnesse.org
    14. Watir : http://wtr.rubyforge.org
    15. Systir : http://atomicobject.com/systir.page
    16. AUT : http://aut.tigris.org/
    17. UnitTest++ : http://unittest-cpp.sourceforge.net/
    18. TestNG : http://testng.org/doc/
    19. CppUnit : http://sourceforge.net/projects/cppunit
    20. CppUnit2 : http://cppunit.sourceforge.net/cppunit-wiki/CppUnit2

  8. 프로젝트 관리

    1. OpenProj : http://openproj.org/openproj
    2. dotproject : http://www.dotproject.net/
    3. Mantis : http://www.mantisbt.org/

  9. 커뮤니케이션 도구, 위키

    1. MoinMoin : http://moinmoin.wikiwikiweb.de/
    2. Confluence : http://www.atlassian.com/software/confluence/
    3. TWiki : http://twiki.org/
    4. SocialText : http://www.socialtext.com/
    5. Springnote : http://www.springnote.com/ko

  10. 성능분석

    1. ANTS Load : http://www.red-gate.com/products/ants_load/index.htm
    2. JunitPerf : http://www.clarkware.com/software/JUnitPerf.html
    3. Jmeter : http://jakarta.apache.org/jmeter/

  11. 기타

    1. Agitar : http://www.agitar.com/
    2. Structure101 : http://www.headwaysoftware.com/index.php
    3. FreeMind : http://freemind.sourceforge.net/wiki/index.php/Main_Page
    4. Capistrano : http://manuals.rubyonrails.com/read/book/17

내 외장하드가 망가진건… 네이버 PC그린 때문인가…ㅠㅠ

어제 3년간 회사에서 자바 개발을 하면서 쌓아온 소중한 자료들이 담긴 160G짜리 외장 하드를 연결했는데.. 폴더랑 파일들이 싹 사라지고 없었다.. 너무 황당했다 돈으로는 환산할 수도 없는 자료들인데..

외장하드 업체에 연락을 해보니 99% 바이러스가 분명하다는… 그런데 난 분명히 네이버 PC 그린을 깔아놓고 잘 사용하고 있었는데 어찌 이런일이…ㅡㅡ; 며칠 전에도 분명 PC 그린으로 바이러스 스캔을 해서 바이러스를 찾았는데 “격리” 라고 나와서 잘 된줄 알았더만… 그게 알고보니 완벽히 치료가 된건 아니고 치료가 불가능해서 단지 “격리”만 시키고 말았다는 소리였다.

원래 2001년에 바이로봇 정품 라이센스를 구입해서 쓰다가 올 초에 처음으로 PC그린… UI가 깔끔하고 예뻐서 한번 바꿔서 써본거였는데…

당장 바이로봇을 설치하고 엔진 업데이트…. 네이버 PC 그린 삭제하고 바이로봇으로 바이러스 스캔을 했다. 한 3시간에 걸쳐서 하드디스크 전체를 싹 스캔하는동안 300개정도의 바이러스가 발견되고 “격리”가 아니라 정확하게 “치료” 되었다고… 휴~

데이타 복구 업체에 이미 외장하드 맡겼는데 복구 비용이 9만원이라는….ㅡㅡ; 실제로 컴터 바이러스 때문에 금전적 피해를 입은건 이번이 처음이다… 뭐.. 중요한 데이타가 아니라면 버려도 되겠지만.. 3년간 근무하면서 쌓은 중요한 정보들이라..

음… 결론은..? 네이버 PC그린을 쓰지 말자…?
내가 알기에 네이버 PC 그린은 “카스퍼스키” 라는 동유럽 바이러스 업체의 백신 엔진을 쓰는걸로 알고 있는데.. 문제는 요 백신 엔진이 아닌가 싶다. 왜 바이러스를 찾아놓고 치료는 못하고 그냥 격리만 시켜놓는지.. (디스크상에서 ‘격리’라는 말이 컴터 전공자의 입장에서 뭔 말인지 모르겠음…)

UTF-8과 EUC-KR로 인코딩 된 파일간의 인코딩 변환 프로그램

UTF-8(유니코드)로 인코딩된 파일을 EUC-KR로… 또는 그 반대로 파일 인코딩을 자동으로 변환하는 툴입니다. 간혹가다 이렇게 유용한 프로그램이 절실한데 찾기가 힘들다는..
특정 폴더만 지정해주고 확장자만 입력하면 해당 폴더 및 그 하위폴더에 해당하는 확장자 모든 파일의 인코딩이 일괄 변환됩니다.
개인 블로그에서 배포하는 것이 올바른 방법은 아니지만 원래 배포하던 분의 사이트가 폐쇄된 상황에다가 개발자들에게 워낙 유용한 프로그램이라 개인 블로그에서 재배포를 합니다..

1079379848.xxx

Spring2.0의 달라진 점 요약

Spring2.0의 달라진 점 요약


이 글은 스프링 프레임워크의 창시자인 Rod Johnson이 InfoQ에 게제한 Spring 2.0: What’s New and Why it Matters 기사를 한글로 요약한 글입니다. 원본 기사는 http://www.infoq.com/articles/spring-2-intro 에서 보실 수 있습니다. Spring 프레임워크가 버전 1에서 2로 올라서면서 무엇이 어떻게 달라진 것인가 대략적으로만 살펴보는 글이기 때문에 상세한 내용을 원하시는 분은 위 URL로 가셔서 원문을 직접 읽어보세요


스프링 2.0의 주요 변경 사항



  • 설정 확장: 스프링 2.0은 확장 가능한 XML 설정을 지원한다. 이는 새로운 (좀 더 상위의 ) abstrace level에서 스프링 빈을 정의할 수 있다는 것을 의미한다. (역주; XML 스키마를 따로 정의해서 빈 정의를 추상화시킨다는 것을 말하는 것 같다.)
  • AOP 프레임워크에 대한 중요한 발전이 있었다. 좀더 강력하고, 사용하기 쉽도록.. (AspectJ와의 모종의 합의?가 있었던것 같음.)
  • Java 5를 지원하도록 발전되었다. (하지만 국내 환경에서 아직 Java 5는 대세가 아니기 때문에 우리에겐 큰 의미가 없는 것 같다.)
  • 스프링 빈이 다양한 언어에 의해 구현될 수 있게 되었다. (Groovy, JRuby, Beanshell 등) 다른 언어를 사용하면서도 Dependency injection이나 AOP와 같은 스프링 컴포넌트 모델은 유지된다.
  • 포틀릿 MVC 프레임워크와 같은 새로운 기능이 추가되었다. 또한 Java Persistence API (JPA)와의 API 통합, 비동기 태스크 수행 프레임워크가 추가되었다.

Rod Johnson은 이번 기사에서는 XML 설정 확장과 AOP, Java 5에 대해서만 언급을 했습니다..!


XML 설정 확장 기능


단순한 bean 태그로만 구성되어 있는 기존의 스프링 XML 설정으로는 뭔가 한계가 있다. XML 스키마를 따로 만들어주어 복잡한 빈 설정들을 단순하게 만들 수 있다.


예를 들어 스프링 1.x에서는 트랜잭션 처리를 위해 다음과 같은 3개의 빈을 설정해 주어야 했다.



<bean     class=”org.springframework…DefaultAdvisorAutoProxyCreator”/>
   <bean class=”org.springframework…TransactionAttributeSourceAdvisor”>
     <property name=”transactionInterceptor                     ref=”transactionInterceptor”/> </bean>


  <bean id=”transactionInterceptor”      
class=”org.springframework…TransactionInterceptor”>
     <property name=”transactionManager”                     ref=”transactionManager”/>
     <property name=”transactionAttributeSource”>
         <bean class=”org.springframework…AnnotationsTransactionAttributeSource”>
        </bean>
     </property>
 </bean>


그러나 스프링 2에서는 기본적으로 제공되는 tx 네임스페이스를 사용해서


<tx:annotation-driven />

단 한줄의 태그 삽입만으로 트랜잭션 설정이 종료된다. 물론 tx 네임스페이스를 사용하겠다고 다음과 같이 스프링 설정 XML 문서에 선언해주어야 한다.



이러한 확장 태그는 기존의 bean 정의 태그와 섞여서 함께 사용될 수 있다.


일단 스프링 2.0에서 제공되는 out-of-the-box 네임스페이스의 목록은 다음과 같다.



  • Transaction management (“tx”): Making Spring beans transactional becomes significantly easier in Spring 2.0, as we have seen. It also becomes easier to define “transaction attributes” mapping transactional behavior onto methods.
  • AOP (“aop”): Specialized tags allow AOP configuration to be much more concise in Spring 2.0 than previously, without the IoC container needing to depend on the AOP framework.
  • Java EE (“jee”): This simplifies working with JNDI and other Java EE APIs, as we have seen. EJB lookups gain still more than JNDI lookups.
  • Dynamic languages (“lang”): Simplifies the definition of beans in dynamic languages-a new feature in Spring 2.0.
  • Utils (“util”): Simplifies loading java.util.Properties objects and other common tasks.

스프링 2.1 이후에는 더 풍부한 네임스페이스가 제공되어 다양한 영역에서 이러한 단순한 설정을 활용할 수 있게 될 예정이다. 물론, 스프링에서 기본 제공되는 네임스페이스 외에 제 3자 (third party)가 제공하는 네임스페이스를 활용하거나 직접 네임스페이스를 정의해서 사용 가능하다. 대표적인 예가 Acegi Security (2007년 상반기 중에 Spring Security로 재탄생될 예정..!) 관련 빈 설정을 한단계 추상화한 예이다.


그러면 어떻게 커스텀 네임스페이스 구현할 수 있을까? 매우 간단하다…! 다음 세 단계를 따라하기만 하면 된다.



  1. XML 스키마를 정의한다. 가장 어려운 스텝이다. 적절한 XML 유틸리티 프로그램으로 작성하면 된다.
  2. 1번에서 정의한 스키마로 부터 BeanDefinition을 생성하기 위해 NamespaceHandler 인터페이스를 구현한다.
  3. spring.handlers 등록 파일을 수정하여 스프링 프레임워크가 새로 생성한 NamespaceHandler를 인식하도록 한다.

http://www.springframework.org/schema/util=org.springframework.beans.factory.xml.UtilNamespaceHandler http://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler http://www.springframework.org/schema/lang=org.springframework.scripting.config.LangNamespaceHandler http://www.springframework.org/schema/tx=org.springframework.transaction.config.TxNamespaceHandler http://www.springframework.org/schema/jee=org.springframework.ejb.config.JeeNamespaceHandler http://www.springframework.org/schema/p=org.springframework.beans.factory.xml.SimplePropertyNamespaceHandler


다수의 spring.handlers 파일은 서로 다른 META-INF 디렉토리에 넣어두고 사용할 수 있다. 그러면 스프링이 런타임에 이들을 하나로 병합하게 된다. 스프링 배포에 함께 포함되는 spring.handler 파일을 열어보면 ‘표준’적인 네임스페이스 설정을 살펴볼 수 있다.


이렇게 XML 확장 태그를 정의해서 사용할 수 있게 된 것은 분명 좋은 일이지만…. 합당한 이유 없이 무분별하게 사용되어서는 안된다. 왜냐 하면 XML 확장 태그를 정의하는 것은 추상화 단계를 더 높이는 일이고 이는 곧 사람들이 뭔가 공부해야 할 것이 늘어난다는 것을 의미하기 때문이다. 이미 스프링의 XML 빈 설정 방식은 수십만의 개발자들에게 친숙해졌는데 분명한 이유 없이 커스텀 네임스페이스를 만들 필요가 있을까….?


다양해진 Bean의 Scope


스프링2.0에서 달라진 것 중의 하나는 bean의 scope가 더 다양해졌다는 것이다. 스프링2.0 이전에는 빈의 스코프 속성으로 Singleton과 Prototype(싱글톤이 아닌것) 2가지가 설정 가능한 것이었다. 그러나 스프링 2.0에서는 커스텀 스코프를 설정할 수 있게 되었다.


웹 어플리케이션에서는 세션에 오브젝트를 담는 방법에 대한 요구 사항이 많았었다. 이 요구는 스프링 2.0의 out of the box에 의해 지원이 될 수 있게 되었다.


<bean id=”userPreferences” class=”com.foo.UserPreferences” scope=”session”/>

이 bean 정의에서 스코프로 디폴트값인 singleton이 아닌 session으로 정의되었다. (커스텀 scope는 어떤 이름으로 줘도 상관 없지만 session과 request는 웹 어플리케이션에서 사용하기 위해 예약되었다.)


userPreferences를 getBean()으로 부르게 되면 스프링은 현재 HTTP 세션으로부터 UserPreference의 오브젝트를 가져오게 된다. 만약 세션에 그런 오브젝트가 담겨있지 않으면 새로운 오브젝트를 하나 생성하면 그만이다. 세션으로 부터 오브젝트를 가져오는것을 가능하게 하려면 web.xml에 다음과 같이 리스너를 더 등록해야 한다.


<web-app>
   …
   <listener>
     <listener-class>
 org.springframework.web.context.request.RequestContextListener
</listener-class>
   </listener>
   …
</web-app>

그런데 만약…. userPreferences빈을 자신보다 더 긴 라이프사이클을 갖는 다른 빈에다 inject시켜야 하는 경우에는..? 예를 들어 스프링 MVC 컨트롤러에서 다음과 같이 userPref를 사용할 수 있다.



public class UserController extends AbstractController
 {
    private UserPreferences userPreferences;
    public void setUserPreferences(UserPreferences userPreferences)
    {
        this.userPreferences = userPreferences;
    }


   @Override
  protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception
 {
  // do work with this.userPreferences
  // Will relate to current user
  }
   }


이 경우 우린 just in time 인젝션이 가능했으면 좋겠다고 생각하게 된다. (역주; just in time injection? 라이프사이클이 더 짧은 UserPref 오브젝트가 userpref를 사용하려고 하는 순간 그때 오브젝트가 resolve되는… 마치 하이버네이트 같은 ORM의 lazy loading과 같은 개념 같다.)


그런데.. 우리가 착각하고 있는게 하나 있다. 바로 스프링의 빈 인젝션이 static하다고 생각하는 것이고 그래서 stateless하다고 생각하는 것이다. 이건 사실이 아니다. 왜냐면 스프링은 AOP 프레임워크이기 때문이다…!  ㅡㅡ;



<bean id=”userPreferences” class=”com.foo.UserPreferences” scope=”session”>            <aop:scoped-proxy/>     </bean>


     <!– a singleton-scoped bean injected with a proxy to the above bean –>     <bean id=”userController” class=”com.mycompany.web.UserController”>          <!– a reference to the proxied ‘userPreferences’ bean –>         <property name=”userPreferences” ref=”userPreferences”/>      </bean> </beans>


이러한 설정으로 이 문제는 쉽게 해결된다.


이제 빈 resolution은 다이내믹하게 발생하게 될 것이다. UserController 안의 userPref 인스턴스는 세션에 있는 UserPref의 오브젝트에 대한 프록시가 된다.


이런 작업들 속에서 세션 객체를 직접적으로 건드릴 필요는 없다. 또한 유닛테스트 때에도 HttpSession 오브젝트에 대한 mock 없이도 테스트가 가능하다. just in time 인젝션에 대한 다른 방법도 있다. (lookup를 사용한건데 이건 그다지 중요한 개념이 아닌 것 같으므로 생략하고 보시길 원하시는 분은 원문을 보시길)


스프링 2.0과 자바 5


스프링 2.0은 자바 5를 지원한다고 하는데 대표적으로 자바5의 generics와 같은 장점들을 활용할 수 있게 만들어준다.



public class DependsOnLists {    private List  plainList;


  private List<Float> floatList;


  public List<Float> getFloatList() {


      return floatList;  }


  public void setFloatList(List<Float> floatList) {    this.floatList = floatList;  }   public List getPlainList() {    return plainList;  }


public void setPlainList(List plainList) {    this.plainList = plainList;  }


}


여기서 plainList는 전통적 방식의 콜렉션이고, floatList는 새로운 방식의 콜렉션이다.


<bean class=”com.interface21.spring2.ioc.DependsOnLists”>      <property name=”plainList”>     <list>        <value>1</value>        <value>2</value>        <value>3</value>            </list>      </property>      <property name=”floatList”>            <list>               <value>1</value>               <value>2</value>               <value>3</value>            </list>      </property> </bean>

이 빈 설정에서 스프링은 floatList를 잘 populate하겠지만


다음 테스트 코드를 보면…



public class GenericListTest extends AbstractDependencyInjectionSpringContextTests {


  private DependsOnLists dependsOnLists;


  public void setDependsOnLists(DependsOnLists dependsOnLists) {     this.dependsOnLists = dependsOnLists;   }


  @Override   protected String[] getConfigLocations() {     return new String[] { “/com/interface21/spring2/ioc/inference.xml” };   }


  public void testLists() {     List plainList = dependsOnLists.get


PlainList();     List<Float> floatList = dependsOnLists.getFloatList();     for (Object o : plainList) {         assertTrue(o instanceof String);         System.out.println(“Value='” + o + “‘, class=” +                                 o.getClass().getName());   }     for (Float f : floatList) {         System.out.println(“Value='” + f + “‘, class=” +                                 f.getClass().getName());     }   }


  }


이 테스트 코드의 결과이다.



Value=’1′, class=java.lang.String Value=’2′, class=java.lang.String Value=’3′, class=java.lang.String Value=’1.0′, class=java.lang.Float Value=’2.0′, class=java.lang.Float Value=’3.0′, class=java.lang.Float


향상된 AOP 기능


스프링2.0의 가장 큰 진보는 AOP를 더 쉽고 간단하게 사용할 수 있게 된 것이다. 스프링 팀에게 있어서 AOP는 가장 중요한 가치였다. 왜냐면.. AOP는 전혀 새로운 생각의 방식을 하도록 하기 때문이다. pure oop로는 해결하지 못하는 다양한 문제들도 AOP 적용으로 쉽게 해결되기도 한다.


스프링 2.0 이전의 AOP에선 약간의 결점이 있었다. (귀찮아서 번역 안했습니다. 죄송…ㅜㅜ) Only simple pointcuts could be expressed without writing Java code. There was no pointcut expression language allowing sophisticated pointcuts to be expressed concisely in strings, although RegexpMethodPointcutAdvisor allowed simple regular expression-based pointcuts to be defined.


XML configuration could become complex when configuring complex AOP usage scenarios. The generic element was used to configure the AOP classes; while this was great for consistency, offering DI and other services to aspects as well as classes, it was not as concise as a dedicated configuration approach.


Spring AOP was not suited for advising fine-grained objects-objects need to be Spring-managed or proxied programmatically.


The performance overhead of a proxy-based approach can be an issue in a small minority of cases.


Because Spring AOP separates the proxy and the target (the object being decorated or advised), if a target method invoked a method on the target, the proxy would not be used, meaning that the AOP advice would not apply. The pros and cons of using a proxy-based approach to AOP are beyond the scope of the article: there are some definite positives (such as being able to apply different advice to different instances of the same class), but this is the major negative.


스프링 2.0에서는….. align with AspectJ in Spring 2.0 하기로 했다.  왜냐면 AspectJ는 풍부한 포인트컷 표현 언어가 있기 때문에…


이 코드를 보면 이해가 갈 것이다.



@Aspect public class AnnotatedBirthdayCardSender {


  @After(“execution(void com.interface21..Person.birthday()) and this(person)”)   public void onBirthday(Person person) {      System.out.println(“I will send a birthday card to ” +             person.getName() + “; he has just turned ” +             person.getAge());   } }


복잡한 XML 설정이 아니라 자바5의 문법을 최대한 활용해서 간단하게 AOP를 구현한 모습이다. (역주; 자바 5의 강점을 멋지게 활용한 것 같습니다… 하지만 개발 환경이 자바2라면 소용이 없다는거…)


그럼 XML로 AOP 포인트컷을 정의해주는 방식과 AspectJ의 방식 중 어느것을 사용할 것인가…?


어느것을 사용해도 무방하지만 다음과 같을 경우에는 꼭 XML을 사용할 것.. Use XML if: You are unable to use Java 5, and have no choice. Spring 2.0’s AOP enhancements, except for processing @AspectJ syntax, work on Java 1.3 and 1.4 as well as Java 5, although you won’t be able to write pointcut expressions matching annotations or other Java 5 constructs.


You might want to use the advice in different contexts.


You want to use existing code as advice, and don’t want to introduce AspectJ annotations into it: for example, introducing an Observer behavior invoking a method on an arbitrary POJO.


AspectJ 방식의 포인트컷 정의 방식을 사용한 예제는 http://www.infoq.com/articles/spring-2-intro 에 있습니다.

자바 코드 내에서 인코딩 변경

우리 회사의 솔루션은 UTF-8 기준으로 만들어졌기 때문에 대부분의 웹사이트에서 사용중인 EUC-KR로 인코딩된 스트링을 UTF-8로 변환할 필요가 있다.

아래 코드를 사용하면 자바 소스 내에서 바로 인코딩 변환이 가능하다.



String euckr = “가나다”;  // EUC-KR
String utf8 = new String(eucStr.getBytes(“euc-kr”), “utf-8″);


모질라 썬더버드 1.5 첨부 파일명이 변경되는 문제

모질라 썬더 버드 (Mozilla Thunderbird) 1.5는 훌륭한 메일 클라이언트이지만 메일을 보낼때 파일을 첨부해서 보내면 받는 사람은 첨부파일명이 ATTxxxxxx.dat 이런 식으로 파일명이 이상하게 변경된 채로 메일을 받게 된다.

이 문제를 해결하려면
썬더버드 메인 윈도우에서 도구-환경설정으로 들어가서
‘고급’ 탭을 연 후 ‘설정 편집’ 버튼을 클릭한다.
새로운 윈도우에서 mail.strictly_mime.parm_folding 의 값을 2에서 1로 바꾸면 이 문제를 해결할 수 있다.

UBR (UDDI Busines Registry) 폐쇄 소식

오늘 아침에 Microsoft, IBM의 UDDI 팀으로 부터 이메일을 받았습니다. 지금까지 운영해오던 UDDI 레지스트리를 폐쇄한다는 메일입니다. 이들이 운영하는 UDDI는 W3C 웹 서비스 기술을 주도적으로 개발해오던 컨소시엄 구성 기업들 (MS, IBM, SAP, HP, NTT)이 전 세계적으로 통용되는 공개 UDDI 레지스트리 클라우드(Cloud)를 구축한 것으로 한 기업의 UDDI에 정보를 등록하면 24시간마다 수행되는 동기화 작업에 의해서 나머지 4개 기업의 UDDI에 정보가 복사되어 결국 겉으로 보기에 하나의 UDDI를 보고 있는 것처럼 구현한 세계 유일의 완전 공개 UDDI 레지스트리였습니다.
그런데 이 UDDI 레지스트리들이 폐쇄된다는 메일을 받고 이유가 뭔지 알아봤더니 이미 UBR을 통해 웹 서비스 기술이 많은 발전을 거듭해왔고 많은 기업, 기관들이 이미 사설 UDDI를 운영중이기 때문에 더이상 UBR을 운영할 필요가 없다는 것입니다. (Now that the benefits of this technology have been realized and many organizations have established their own UDDI registries, the IBM-hosted UBR will be discontinued.)
이들 기업들이 비영리 목적으로 운영하는 UBR이 웹 서비스 관련 기술 발전에 많은 기여를 한 것은 사실이지만 웹 서비스 기술 개발과 표준화에 선구적인 역할을 해왔던 이들 기업이 한꺼번에 UBR을 폐쇄한다는 것이 약간은 성급한 결정은 아닌가 생각됩니다.
마이크로소프트와 IBM으로 부터 받은 이메일을 첨부합니다.



From Microsoft



You are receiving this mail because you have registered as a publisher on the Microsoft node of the UDDI Business Registry (UBR).



The primary goal of the UBR was to prove the interoperability and robustness of the UDDI specifications through a public implementation.  This goal was met and far exceeded, and now the UBR is discontinuing its operations. As part of this process the Microsoft UBR node at uddi.microsoft.com will be permanently unavailable for all operations beginning January 12, 2006.  Data stored in the UBR may be retrieved until January 12, 2006 and used in accordance with the UDDI Business Registry terms of use available at http://uddi.microsoft.com/policies/termsofuse.aspx.  You may find the UDDI Data Export Wizard useful for retrieving your data, and it is available here: http://www.microsoft.com/downloads/details.aspx?familyid=9D467A69-57FF-4AE7-96EE-B18C4790CFFD



For more information, please see the frequently asked questions related to the UBR discontinuation at http://uddi.microsoft.com/about/FAQshutdown.htm.  You may submit feedback to Microsoft at the following location: http://uddi.microsoft.com/contact/default.aspx.



Thank You,
Microsoft UDDI Team






———–
From IBM



You are receiving this notice because you registered at one of the IBM
UDDI sites. The IBM UDDI Business Registry, the IBM UDDI Test
Registry and the IBM UDDI Beta Test Registry web sites will no
longer be available as of January 12, 2006.



In February 2005, the Version 3 of the Universal Description, Discovery
and Integration (UDDI) V3 was approved as an OASIS standard. Having
achieved that milestone, the companies hosting the UDDI Business
Registry (UBR) evaluated the results of hosting a reference
implementation for the UDDI technology. Over the past five years, as
Web services applications have matured, the role of UDDI based
registries has also evolved in part based on testing experiences with
UBR. Registries based on UDDI have been established within enterprises
and organizations and have an important role in Web services business
applications. The availability of UBR provided valuable validation and
guidance during the early days of UDDI. Now that the benefits of this
technology have been realized and many organizations have established
their own UDDI registries, the IBM-hosted UBR will be discontinued.



IBM will continue to support UDDI in WebSphere and Rational software
products and tooling. The UDDI support in IBM products is not affected
by this announcement. Also, you may continue to use the same IBM
profile account and password to log into any other ibm.com web sites or
web applications.



Before January 12, 2006, you will still be able to access any
information from the UDDI sites using the web interfaces or Web service
APIs. The login pages for the sites are:



IBM UDDI Business Registry: https://uddi.ibm.com/ubr/registry.html
IBM UDDI Test Registry: https://uddi.ibm.com/testregistry/registry.html
IBM UDDI V3 Beta Registry: https://uddi.ibm.com/beta/registry.html



A Frequently Asked Questions document regarding this announcement has
been posted at https://uddi.ibm.com/ubr/ibm_shutdown_faq.html
Questions may be directed to our support email address at
uddisupt@us.ibm.com until January 11, 2006.



Thank you for supporting the UDDI project and providing us with valuable
feedback which allowed us to complete our goal of establishing UDDI as
a mature Web service standard.



Regards,



Andrew Hately
IBM UDDI Business Registry Team