Apache Projects/Maven2009/07/01 13:23

Maven에 아직까지도 익숙하지 않은 나로서는 플러그인 자체만으로도 어렵게만 느껴진다.
그래서, Maven이 제공하는 플러그인에 대해서 정리하고자 한다.

 플러그인 설명 
 clean  빌드 이후에 클린 업
 compiler  자바소스 컴파일 
 deploy  원격 리포지토리에 built artifact를 배치 
 install  로컬 리포지토리에 built artifact를 배치
 resources  JAR 파일 안에 포함될 리소스를 output 디렉토리에 복사 
 site  현재 프로젝트를 위해 사이트 생성
 surefire  분리된 클래스로더 안에서 Junit 실행
 verifier  통합 테스트(integration tests)

저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License

'Apache Projects > Maven' 카테고리의 다른 글

Maven 플러그인 목록  (0) 2009/07/01
Maven - FAQ로 알아본 Maven  (0) 2009/02/25
Maven - Archetype 이 무엇인가?  (0) 2009/02/25
Apache Maven Project - 다시 시작하기  (0) 2009/02/23
Maven 첫 실행  (0) 2008/11/14
Posted by toriworks
자바 아티클2009/06/24 15:30
구체적인 클래스를 사용할 때보다 인터페이스를 사용하면 약간의 복잡성을 가중시키지만, 투자에 비해 얻는 것이 크다.
(expert on-on-one J2EE 설계와 개발 - 로드존슨)

로드존슨이 말한인터페이스 기반의 프로그래밍이 갖는 장점은 아래와 같다.

1. 호출하는 코드에 영향을 미치지 않고, 애플리케이션 객체의 어떤 구현 클래스도 변경시킬 수 있다.
2. 인터페이스 구현이 자유롭다. 상속 계층에 얽매일 필요가 없다. 그러나 인터페이스에서 구현에서도 구체적인 상속을 이용하여 코드를 재사용할 수 있다.
3. 필요에 따라 간단한 테스트 구현과 인터페이스의 스텁 구현을 제공할 수 있는 - 이는 다른 클래스의 테스트를 수월하게 하고, 인터페이스에 합의한 후에 여러 팀들 간의 동시적인 작업 수행이 가능하게 해준다.



지금하고 있는 프로젝트에는 인터페이스는 전혀 사용되고 있지 않다. 기본 설계는 누가 했는지 잘 모르겠지만, 무조건 구체 클래스로 모든 것을 처리하고 있다. 동작하지 않는게 아니니, 사실 Refactoring이 꼭 필수불가결하다고 할 수도 없다. 그냥 그렇게 설계되어 있고, 그렇게 또 사용하고 있으며 그렇게 동작하고 있다.
 
헌데 약간의 아쉬움이 있다는 걸 최근에야 알게 되었다. 이 소스를 전 개발사에서 일부 개발하고 우리에게 넘기기도 했지만 제대로 된 문서 한장이 없기에 도대체 이 메소드가 어떤 역할을 하는지 알수가 없다는게 문제다. 그러니, 거의 유사한 기능을 하는 메소드 임에도 불구하고 비슷한 기능의 메소드를 또 하나 더 만들어 쓰고 있더라는거다. 게다가 메소드에 주석 한 줄 없는 이 소스를 분석할 시간도 없으니, 차라리 새로운 메소드를 만들어 쓰는게 더 빨리 문제를 해결하는 길이다.

인터페이스로 메소드를 빼 주었더라면, 거기에 주석이라도 달아주었더라면... 이미 딱딱해진 빵에 아무리 버터를 발라도, 딱딱해진 빵이라는데는 변함이 없다.(클라이언트는 이 딱딱해진 빵을 보드랍게 만들어 달라고 고집을 피우고 있다.) 이런 아쉬움 속에 프로젝트는 막바지를 달려가고 있다. 다시 한번 설계를 한다면 어떻게 해야 할까? 그런 아쉬움이 언뜻언뜻 든다.




저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by toriworks
기타2009/06/23 15:36
Tiles와 Sitemesh에 대한 블로그가 있길래 (기선님의 노트 중 http://whiteship.me/2216) 어떤게 더 많이 사용되고 있는지를 살펴보았습니다.

구글에서 제공하는 Trends라는 웹사이트를 통해서 비교를 해보았습니다. Tiles라는 단어가 워낙 범위가 넓은지라 정확한 데이터가 맞는지 확신이 서지를 않는군요. 비교는 sitemesh와 tiles 2라는 단어로 해 보았습니다.


직접 비교해 보실 분은 http://www.google.com/trends 주소를 따라가서 해 주시면 됩니다. 비교 시 구분자는 쉼표(,) 입니다.
그래프를 봐서는 우열을 가리기 힘든데요.


기선님은 총 4가지로 Tiles와 Sitemesh를 비교를 해 두셨군요.
  재사용성  설정  실행중 설정  성능 
 Tiles (Compsite View Pattern)  O  
 Sitemesh (Decorator Pattern)      

Tiles가 총 3표를 Sitemesh가 겨우 1표를 획득했네요. 제 경험에 비추어 보면, Tiles로 할 때 왠지 더 많은 노력이 들어간 것으로 생각됩니다. Sitemesh는 설정하기가 아주 쉽다는 생각이 많이 들어서였는지는 몰라도 Spring으로 개발할 때는 Sitemesh를 주로 사용하고 있기도 합니다. 편한 걸 선호하는 건 아마도 인간의 본능이 아닌가 생각되기도 하네요.(나태한 걸까요? 제가?) 한편 Tiles는 Struts 개발 할 때 주로 사용했구요.




이번에 새 프로젝트를 하게 되는데, 프로젝트와 관련해서 교육을 받고 왔습니다.
레이아웃에 대한 솔루션 교육이었는데, Tiles나 Sitemesh는 아니었지만 열심히 들었습니다. 돌이켜 교육 내용을 곰곰히 생각해보니, 그 솔루션은 Tiles에 가깝다는 생각이 듭니다. 제가 본 솔루션이 Tiles의 아류일까요? 더 지켜봐야겠습니다.


결론은 이렇습니다.
Tiles - "설정은 어렵지만, 재활용성은 뛰어나다." 
Sitemesh - "재활용성은 좀 떨어지지만 설정이 쉬워서 쓰기는 쉽다."







저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by toriworks
기타2009/05/31 14:53

이메일이라고 하는 게 나온지 꽤 오래인데, 아무도 이메일에 대해서 왈가왈부한 적은 없었던 걸로 기억된다. 다만, 이메일에 첨부파일 용량이 몇 기가네 그 정도로만 그쳤던게 사실이다.
이제 Google이 그 이메일을 뒤집을 모양이다. Google maps 이후로 업계에 미친 파장을 다시 파도로 이어갈 모양이다. 당장 Google maps 개발을 담당했던 개발자가 Google wave의 개발자임을 볼 때 얼마나 Ajax를 현란하게 도입할 게 예상되어진다.


저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by toriworks
ANDROID 스터디2009/05/05 00:53
android create avd --target 2 --name my_avd
또는
android create avd -t 2 -n my_avd

이렇게 입력 후에
emulator -avd my_avd
저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License

'ANDROID 스터디' 카테고리의 다른 글

안드로이드 1.5에서 주의 할 점  (0) 2009/05/05
개발과 디버그  (0) 2008/11/11
Posted by toriworks
자바 아티클2009/04/14 13:48

만약 위와 같은 에러를 보게 된다면, 재앙이다.


jsp 로 프로그래밍을 하는데, "Code of a method longer than 65535 bytes" 라는 에러가 발생했다면 손 쓸 길이 없어진 환자나 다름없다. 아무리 CPR을 한다쳐도, 그닥 효과가 없다. 약간의 과장이 들어가긴 했지만, 위와 같은 에러는 아직까지도 그다지 좋은 해결방법이 없는 그런 오류다.

자바 클래스파일이 64k로 한정되어 있다고 하는 소문을 들은적이 있는가? 64k 이상은 에러가 발생한다고 들은적이 있는가?
"Code of a method longer than 65535 bytes" 오류가 바로 그 녀석이다. 64k가 넘은 클래스 파일은 그 구문이 정당하다고 해도 오류로 잡힌다.

해결책은 그럼 무엇인가?
구글을 아무리 뒤져봐도 질문만 있지, 답변은 찾아보기 힘들다. 심지어 Sun에 하소연하는 사람까지 있다. 하지만, 간당간당하게 저 오류를 넘나들고 있다면, 딱 하나 방법이 있긴 하다.

주석을 모두 삭제한다.
줄 띄어쓰기를 모두 없앤다.


뭐냐 64k 아래로 클래스 파일이 나오도록 최대한 불필요한 부분을 없애라는 거다. 근본적으로 파일을 64k까지 만든 사람이 잘못이니까!!! 몇 천줄이 넘는 소스가 온당한 소스인가 싶다.(유지보수 하자니 죽겠다.) 어찌되었던지간에 주석과 줄 간격을 모두 없애고, 불필요한 import와 사용하지 않는 변수들을 모두 삭제해 버리고 나니 위 오류가 없어졌다.

보다 근본적인 해결책이 있다면 답글을 부탁한다. 헐헐헐...
저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by toriworks
기타2009/04/02 21:40
오늘 저녁메뉴로 나온 만두탕수(군만두에 탕수육 소스가 뿌려진 음식)에 대해 잠깐 동료들과 이야기 하면서 나온 걸 적어봅니다.

명칭에 대한 거였는데, 군만두에 탕수육 소스가 담뿍 뿌려진 음식의 이름으로 탕수만두가 맞는지 아니면 만두탕수가 맞는지에 대해 생각해 보았다. 결론적으로 식단표에 적혀 있는 메뉴를 보니 만두탕수였다. 이 음식이 만두탕수가 되어야 할지 아니면 탕수만두가 되어야 할지에 대해서는 의견이 분분했다.



첫번째, 만두탕수가 될 수 없는 이유.
만약에 만두탕수라는 이름이 맞는 거라면, 우리가 흔희 짜장집에서 시켜먹는 탕수육은 육탕수라고 불러도 무방해야 하는가? 아니다 분명히 육탕수라하지 않고 탕수육이라고 한다. 탕수육의 탕수라 함은 한자어로 糖水(단물) + 肉(고기)이기에 고기에 달달한 물을 뿌려(적셔, 담가, 찍어, 쳐 등등...) 먹는 걸 말하는 걸로 생각된다. 물론 탕수육 자체는 한 단어의 고유명사이다.
우리가 육탕수라 하지 않고, 탕수육이라고 하듯이 만두에 탕수육 소스가 들어간 음식의 이름은 당연히 탕수+만두, 즉 탕수만두가 되어야만 하는 것이다.



두번째, 만두탕수가 될 것도 같은 이유.
동료 중 하나가 첫번째 이유가 보편타당함에도 불구하고 딴지를 걸었는데, 그것은 바로 조리법의 미묘한 차이가 있지는 않은것인가? 라는 것이다. 조리법에서 오는 차이점이 이름을 만두탕수 또는 탕수만두로 불리게 할 수 있지 않냐라는 의외의 지적이 있었다.
요는 이렇다. 만약에 만두에 탕수육 소스를 부어서 음식을 만들었다면 그것은 당연히 탕수만두가 된다. 하지만, 역으로 탕수육 소스에 만두를 부어서(만두가 소스 또는 토핑 정도로 취급됨) 비벼서 만들었다면 탕수육 소스에 만두가 나중에 소스 처럼 부어졌기 때문에 탕수만두로 명명해도 좋다는 것이다.



만두탕수냐 탕수만두냐의 승자는 서두에도 밝혔듯이 만두탕수였다. 그렇다면, 위의 얼토당토하지 않은 가정을 통해 살펴보자면 두번째 가정이 설득력을 얻게 된다.(가정이 두가지 밖에 없으므로 어쨌든 껴 맞춰서) 어허... 그렇다면 우리가 저녁으로 먹은 그 메뉴의 조리법까지도 유추가 가능하게 되는 것이다. 아마도 우리가 보지 못하는 사이에 거대한 탕수육 소스 그릇에 튀겨진 만두가 푸덕푸덕 부어졌다는 것. 그리고 조리장의 열심을 다한 삽질의 결과가 저녁 메뉴로 나온 그 이름하야 만두탕수인 것이다.


결론을 내보자.
잠시 잠깐의 저녁식사 시간의 유쾌한 농담이었지만, 새삼 한글의 재미(이런건 한글날 생각해야 하는건데...)가 느껴지는 유희였다. 요즘 식단이 피폐해져가는데에 대한 역습일 수도 있다. 아무리 얻어먹는 밥이긴 하지만, 나름 아쉬움에 이런 농으로라도 나 자신을 달래보고자 한다. 허허허. 난 오늘 점심에 그래도 엄마가 해준 밥 먹었다. 

저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by toriworks
Spring framework2009/03/28 08:35
생성자를 이용한 의존성 주입

주로 setter 메소드를 통해 의존성을 주입하기는 하지만, 이 이외의 방법이 없는 것은 분명 아니다.
생성자를 이용해서 의존성을 주입할 수 있는데, setter 메소드를 이용한 방법과는 사뭇 다른 모양새를 가지고 있으니 필요에 따라, 목적에 따라 이용할 줄 알아야 한다.

공실장 : 김과장, 난 언제나 setter 메소드로 의존성 삽입을 하고 있는데 말이지. 생성자를 이용한 의존성 삽입의
            방법도 있더군. 그런데, setter 메소드로 다 할 수 있는데 굳이 생성자를 통해서 주입할 이유가 있나?
            존재의 이유를 모르겠어.
김과장 : 다 이유가 있겠죠. 생성자의 동작방법을 생각하면 응용이 가능하리라 생각됩니다. 기본생성자 말고, 아규먼트를
            받는 생성자 말이죠.
공실장 : 생성자 동작방법? 파라미터를 받는 생성자?
김과장 : 아규먼트를 받는 생성자의 역할이 주로, 내부 변수 초기화에 사용되잖아요. 이런 역할이라면 Spring에서도
            마찬가지 역할을 기대하면 되겠죠. 다만, Spring의 개념을 추가해서 생각해 보면 외부에서 객체 내부 변수 값을
            1회에 한해 설정을 하도록 하는 거라고 보시면 될 것 같습니다.
            물론 java 파일에서 할 수도 있지만 나중에 혹시 이 기본 세팅값이 변할 수 있다면, java 파일을 찾아서 바꾸고
            재컴파일을 하는 것보다는 외부 파일에서 손 쉽게 세팅값을 변경하는 것도 나쁘지 않다고 생각이 들어요.
공실장 : 그렇군. 외부 파일이라는게 xml 파일을 말하는거군. 듣고보니 생성자를 이용한 의존성 주입도 가끔 사용할 곳이
            있을 수 있겠군.

이미 위의 대화에서 결론이 났지만, 언제 생성자를 이용한 의존성 삽입을 하면 좋을까?
객체를 생성시에 몇 개의 아규먼트를 전달하여 내부 변수에 그 값을 세팅하고자 할 때 사용하면 적당할 것으로 생각된다. 물론 내부 변수에 대해서 각각 setter 메소드를 제공해서 값을 넣어 줄 수도 있지만, 내부 변수에 값이 객체 생성시에 꼭 필요하거나 혹은 한번 주입 후에 절대 값이 변할 것 같지 않다면 생성자를 이용한 의존성 주입법이 적당하다.

일반적인 생성자의 동작방법을 생각해 보면 위의 내용이 이해가 될 것이다.



공실장 : 김과장, 이거 생성자를 이용한 주입을 사용해 보니 가끔 내가 생성자에 넘겨줄 값을 xml 설정에서 빼 먹고 있었
            지뭐야. 실수를 유발할 수 있겠어. 어떻게 하면 실수를 막을 수 있지?
김과장 : 예측 가능한 실수라면 미리 손을 써두는 방법을 생각해야겠죠. 생성자 인자가 혹시라도 누락되면 Exception을
            발생하게 하면 좋을 것 같습니다.
공실장 : 그렇군. Exception을 발생시켜서 어디서 어떤 오류가 있는지 체크하면 되겠군.
            근데, 생성자를 이용한 주입에서는 어떻게 Exception을 내도록 하지?
김과장 : Spring에 Assert 클래스가 있는데, 그걸 이용하면 좋을 것 같아요. JUnit에 있는 assert와 유사해요.
공실장 : Assert 클래스?


생성자를 통한 의존성 주입시에, 혹시라도 생성자에 전달해야 하는 아규먼트를 빼먹고 전달하지 못하는 경우에는 어떻게 하면 좋을까? Spring에서 제공하는 클래스에 Assert 라는 클래스가 있다. Pro Spring 2.5 의 예제를 살펴보자.
public class ConfigurableEncyclopedia implements Encyclopedia {
    private Map<String, Long> entries;
 
    public ConfigurableEncyclopedia(Map<String, Long> entries) {
        Assert.notNull(entries, "The 'entries' argument cannot be null.");
        this.entries = entries;
    }
}

만약에 생성자에 전달하는 아규먼트가 null이라면 위의 코드에는 적절한 Exception이 발생하게 된다. 이 경우 IllegalArgumentException 이 발생하게 된다.



공실장 : 생각보다 생성자를 통한 의존성 주입에 대해 알아야 할 게 많군.
김과장 : 또 주의해야 할 게 있는데, 생성자를 통해서 의존성을 삽입시에 xml 설정에 값을 기록하면 1차적으로 그 값은
            문자열로 처리되서 아규먼트로 넘어오게 되요.
공실장 : 숫자를 넣어도 말인가?
김과장 : 네, <constructor-arg value="1" /> 이라는 코드가 있을 때 여기서 value 는 문자열이지 int 로 처리되지는
            않아요.
            그래서, 아규먼트로 넘어가는 값을 설정할 때 타입을 적어주는게 더 안전한 코딩방법이죠.
공실장 : 그렇겠군. 아규먼트로 넘어가는 값이 특정한 타입입니다 라고 적어주면 안전하겠군.
김과장 : 네, 아규먼트를 받는 쪽이 int 값을 원하는데 문자열을 넘겨주면 안되겠죠. 하지만 xml 설정에서는 문자열 밖에
            넘겨줄 방법이 없기 때문에 타입을 적어주면 문제가 해결되죠. 간단하게도 type 이라는 프로퍼티가 있으니 그걸
            이용하면 됩니다.
공실장 : 타입을 함께 적어줘라. 근데, 문자열로 아규먼트를 넘길 때는 굳이 적을 필요는 없겠지?
김과장 : 네, 전달받을 쪽이 문자열로 받을 거라면 굳이 type 에 값을 적어줄 필요는 없습니다. default로 문자열이라고
            생각하시면 됩니다.

int 로 설정된 내부 변수에 생성자를 통해 값을 넣을 경우에는 xml 설정에서 type을 지정해서 int로 세팅되도록 알려줘야 한다. 왜냐하면, Spring 에서는 xml 설정시 아규먼트를 전달하면 기본적으로 문자열로 인식하기 때문이다. type을 지정하지 않은 경우에는 당연하게도 전달받은 인자가 형식이 맞지 않는다는 오률르 보게 될 것이다.
이 경우는 <constructor-arg value="1" type="int" /> 와 같이 전달할 값이 분명히 int 임을 표시 해야 한다.



생성자를 이용한 의존성 주입을 살펴보았는데, 크게 3가지 이슈가 있음을 보았다.
첫째, 언제 사용해야 하나?
둘째, 아규먼트가 제대로 전달되지 않을 경우
셋째, 아규먼트의 타입을 지정하고 싶은 경우

이 세가지 정도만 이해하고 있다면, 생성자를 이용한 의존성 주입에 대해 걱정하지 않고 사용할 수 있을 것이라 생각된다.





저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License

'Spring framework' 카테고리의 다른 글

Spring Framework Basic - Using Constructor Injection  (0) 2009/03/28
Spring 2.5 실무프로그래밍  (0) 2009/03/20
SpringFramework - FactoryBean  (0) 2009/02/18
SpringFramework - Lookup method injection  (0) 2009/02/17
Pro Spring 3 출간  (2) 2009/02/17
MultiActionController  (0) 2009/02/12
Posted by toriworks
기타2009/03/23 23:12
Jar 명령어로 zip 압축풀기

적어도 자바 세상에서 jar는 익숙한 키워드임에 틀림이 없다. 라이브러리를 배포할 때, 주로 jar 파일 형식으로 제공하기 때문이다.

공실장 : "어 오류나네... 혹시 jar 파일이 없는거 아냐?"
김과장 : "혹시 jar 파일 library 폴더에 안 넣으신거 아니에요?"
공실장 : "그러게, 분명히 넣어줬는데 import에서 에러나네..."

이런 대화는 자바 (웹)개발에서 흔히 볼 수 있는 장면이다. 이건 그렇다치고, jar 명령어로 zip 파일을 푼다는건 또 뭐냐?



jar로 .jar 형식으로 묶어는 봤지만, zip 파일을 풀어본적이 없으니 한번 풀어보도록 하자.
1. 콘솔을 켠다.
2. zip 파일위치로 이동한다.
3. 명령어를 입력한다.(압축파일명이 zipped_something.zip이라 가정하자.)
   jar xvf zipped_something.zip
4. 결과는 현재 디렉토리에 해당 파일명으로 된 폴더를 만들고, zip 파일을 그 안에 풀어준다.


신기하게도 Linux에서 tar 압축푸는 명령어와 닮았다.
테스트 결과, zip 파일은 100% 압축이 풀렸고 tar 나 rar 등은 압축이 풀리지 않았다.
저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by toriworks
BlazeDS overview

BlazeDS 는 클라이언트 어플리케이션으로 부터 서버 데이터에 접속하도록 해주는 서비스의 세트를 제공한다.

클라이언트 어플리케이션과 서버 어플리케이션 이라는 두 개의 파트로 구성된다.
클라이언트는 전통적으로 Flex나 AIR다. 이 두개는 BlazeDS 서버와 통신하기 위한 컴포넌트로 RemoteObject, HttpService, WebService, Producer, Consumer component 를 포함하고 있다.


BlazeDS server
BlazeDS 서버는 J2EE 기반의 어플리케이션 서버위에서 동작한다. BlazeDS는 3개의 파일을 웹 어플리케이션 개발시 포함, 수정해야 한다.

1. BlazeDS Jar 파일과 의존성이 있는 Jar 파일을 WEB-INF/lib 디렉토리에 추가하기
2. WEB-INF/flex 디렉토리 내의 BlazeDS 설정파일 수정하기
3. WEB-INF/web.xml 파일에 MessageBrokerServlet 설정하기
(발췌자설명) 이 MessageBrokerServlet은 만약 Spring BlazeDS Integration을 사용할 경우, 설정에서 제외한다.
                 대신, MessageBroker 빈 설정을 Spring의 configuration 파일에 해 주면 된다. 이것을 Spring-managed 라
                 표현한다. Spring BlazeDS를 사용하는 이유는 MessageBroker 자체를 하나의 빈으로 사용할 수 있고, Spring
                 의 장점이라 할 수 있는 IoC 기법을 사용할 수 있기 때문이다.





BlazeDS features

   [이미지 원본] http://livedocs.adobe.com/blazeds
    /1/blazeds_devguide/images/blazeds_features.png

   BlazeDS는 2개의 Service와 1개의 Adapter로 이뤄져있다.

   1. RPC services
   외부 데이터에 접근을 목적으로 한다. RPC 서비스는 원격지에
   비동기적 요청을 하고 클라이언트에 데이터를 전달하도록 해준
   다. HTTP GET, POST(Http services)나 SOAP(Web services)
   혹은 Java object(remote object services)를 포함한다.
 
   2. Messaging service
   Messaging 서비스는 비동기적인 메시지를 서버와 클라이언트
   가 주고받도록 해준다.
   클라이언트는 "producer"라고 불리는 메세지들 전송한다. Flex
   에서는 Producer component를 사용한다. 그리고,
   클라이언트는 "consumer"라고 불리는 메세지를 전달받는다.
Flex에서는 Consumer component를 사용한다.
저작자 표시
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by toriworks