2012-08-29

Junit에서 Hamcrest 최신버전 사용하기

maven pom.xml을 다음과 같이 바꾸면 됩니다.

<dependency>
    <groupId>org.hamcrest</groupId>
    <artifactId>hamcrest-all</artifactId>
    <version>1.3</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit-dep</artifactId>
    <version>4.10</version>
    <scope>test</scope>
</dependency>

요약하면 junit을 junit-dep 이것을 사용하면 됩니다. hamcrest를 뺀 것이죠.

2012-08-28

Spring ROO 적용

spring mvc 로 잘 만들고 있던 프로젝트였는데, 갑자기 Roo 가 눈에 들어왔다. Roo의 ActiveRecord가 좋아 보였던 것. 그리고 Controller들의 기본 구현 등...

머.. 사실 ActiveRecord 를 쓸지, Repository를 쓸지 아직 고민이긴 하지만..

딴거 할일은 많았지만... 이미 내 손은 Roo를 적용하고 있다. ㅠㅠ.

기존 프로젝트를 Roo기반으로 바꾸면서 일어 났던 일을 (뒤늦게)기록해 본다. (처음부터 기록하면서 작업했으면 좋았을걸)

아무래도 Roo가 생각하는 기본 프로젝트 구조가 있기 때문에, 테스트로 Roo 프로젝트를 하나 만들고 jpa, web mvc 까지 다 세팅한 다음, 이 놈을 참고 하면서 작업하는 것이 좋을 것이다.

우선 web.xml.

web.xml에 스프링의 xml 설정 파일을 지정하는데, roo는 기본적으로 소스의 resources 쪽에다가 applicationContext.xml 을 만들고, WEB-INF 쪽에 webmvc-config.xml 를 만들고 있다. 나도 그에 따라서 spring의 xml 파일 대거 리팩토링!

그리고 나는 hibernate를 쓰고 있었는데, roo는 jpa를 선호하는 것 같으니 jpa설정까지 해 줌. (설정을 복사하는 수준).

덕분에 pom.xml 파일도 수정이 필요했는데, roo프로젝트의 pom.xml을 참고해서 빠진 것들 복사함.

그런 다음 roo shell에서 jpa setup 명령했더니 ... 별로 하는 일 없음. 내가 이미 다 했음.

이제 도메인 클래스들을 손볼 차례인데, 이 부분이 작업이 크다. Controller, Repository 모두 손봐야 한다.

이제 entity jpa --class <기존 클래스> --testAutomatically
했더니.. 뜨아... 내 클래스 덮어 씀. 그냥 기존 클래스 위에
@RooJavaBean
@RooToString
@RooJpaActiveRecord
@RooEquals
네개의 annotation 추가. 글고 테이블에 version 칼럼 추가.

이 때, 다른 화면을 실행 해보니 동작은 함. 하지만 jpa가 사용되고 있는 것은 아니고 여전히 hibernate 기반으로 동작하는 것이겠지. 방금 수정한 entity에 대한 controller는 에러 남.

IllegalStateException  Post-processor tried to replace bean instance of type XXX with (proxy) object of type [YYY] not supported for aspect-configured classes


하지만 

java.lang.IllegalStateException: Post-processor tried to replace bean instance of type [kr.co.gaon.irs.basic.Bank] with (proxy) object of type [$Proxy112] - not supported for aspect-configured classes!


왠지 늪에 빠진 느낌. 글고 sts 3.0으로 하고 있는데 이게 아직 안정화가 덜 되서 그런지 너무 느리다. 도대체 뭘 하고 있는지 모르지만 cpu는 100~200% 기본이고...

sts 재시작 한 번 해주고... (씁쓸하구만...) 그래도 문제 해결은 안되고...

검색해보니 @Configurable 과 @Transactional 을 같이 쓸 수 없다는 얘기가 나온다. 아니다. 어라... 되네? 아까 Build Automatically를 잠시 꺼두었던거 때문인가? 

계속하자. 이젠 Table 이름을 잘못 찾아가고 있다. @RooJpaActiveRecord(table="BankAccount") 라고 했는데, bank_account 라는 테이블로 sql이 날아간다. 
이 문제는 persistence.xml 에서 ImprovedNamingStrategy 때문에 발행하는 것. comment out하자.

이제 동작한다. 휴~~

하지만... 왜 일케 메모리 사용량이 많은겨... reload 한 번 하면 2G를 채워버리네...

<Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/>
이 녀석 때문인가? 


javaagent 방식으로 바꾸니 좀 낫구나. 아니다. 마찬가지구나.

<context:load-time-weaver aspectj-weaving="autodetect" />
삭제해도 잘 동작한다. 지우니 메모리 사용량이 떨어졌다.

오늘은 일단 여기까지.

2012-08-20

맥에서 vmware로 맵피 설치

맥에서 맵피 업데이트 하려고 vmware fusion 에서 삽질하고 있는데, xp가 sd카드를 자꾸 write protected로 인식해서 할 수 없이 깨끗한 xp vm에서 하니 제대로 sd 에 쓸 수 있게 되었음.

그런데 맵피 Smart Connector 가 한글이 다 깨지고... (내 xp가 영문버전이라 그럴 수 있음. 하지만 예전에는 잘 나왔다구!)

대충 설치에는 문제 없겠지 하며 전체설치를 진행하는데 이젠 머 다운로드가 안돼. 몇번을 해도 안돼. 또 다운로드 안돼서 설치 중단된 것 같은데 왜 오류보고 보낼라 그러나? 그러지 말라고 체크박스를 uncheck하려해도 클릭할 수 없다. ㅋㅋㅋ 할 수 없이 그냥 확인.


결국 오늘은 설치 포기. 내일 다시.

update. 08.22) 프로그램의 한글이 깨지는 이유는 XP 언어 설정 중에 유니코드가 아닐 경우 사용할 인코딩 설정이 영어로 되어 있었음. Korean 으로 바꿀려 했더니 xp 씨디 넣어라 하네. 귀찮음. 어쨌거나 이 설정 때문에 음성파일이 다운로드가 안되고 있었음.

eclipse의 tomcat launch configuraton

이클립스 workspace를 dropbox 폴더 안에 두고 사용하는데, 드랍박스가 너무 고생하는 것 같아 톰캣 webapp 경로를 temp 디렉토리로 변경했음.

-Dspring.profiles.active=DEV -Dcatalina.base="/Users/shawn/temp/wtp" -Dcatalina.home="/Users/shawn/apps/tomcat" -Dwtp.deploy="/Users/shawn/temp/wtp/wtpwebapps" -Djava.endorsed.dirs="/Users/shawn/apps/tomcat/endorsed" -Xmx1024m -XX:MaxPermSize=512m

2012-08-13

@PathVariable 이름만 바꾸었을 뿐인데

두개의 컨트롤러에서 같은 시그너처의 핸들러가 메소드만 다르고 모두 같을 때(클래스 레벨 매핑까지), 스프링 시작하면 에러 난다. 같은게 있다고. 이럴 수가... 했는데

PathVariable 이름을 바꾸니 된다. 헉. 그렇다면 PathVariable 이 없을 때는 어떻게 되나? 에이 테스트하기 귀찮아.

예방접종 안하는 이유

어린이 집에서 왜 예방접종을 안하는지에 대해 부모님의 의견서가 필요한 모양이다. 자꾸만 제출해 달라고 독촉이 온다.

현재 우리 아이는 29개월이다. 아직까지 한번도 예방접종을 하지 않았다. 현재 매우 건강하다. 밥도 매우 잘 먹고. 몇 번의 열과 감기 증상이 있었지만 병원과 한의원을 오가며 진찰을 받고 적절히 판단하여 필요하다면 약을 먹이거나, 혹은 굳이 먹일 필요가 없다고 판단될 때에는 각탕과 같은 요법을 처방했더니 스스로 이겨 내었다. 밥도 뚝딱 잘먹고 병치레도 거의 없으니 참으로 고마운 일이다. 아는 후배의 경우 아이가 자주 아파 걸핏하면 병원에 간다는데 우리는 그럴 일이 없으니...

사실 이렇게 건강한데에는 집사람의 노력이 컸다고 생각한다. 임신전, 임신중에도 스스로 먹거리를 매우 조심했고 운동도 열심히 했는데, 사실 이게 쉬운게 아니다. 우리가 일상에서 먹는 군것질 대부분이 아이에게 좋지 않다. 엄마의 건강이 아이의 건강이라고 했을 때, 우리 아이가 건강한 이유의 99%가 이러한 엄마의 노력 때문일 것이라고 생각한다. 지금도 군것질은 하지 않으려고 노력하고 있다. (그런데 요즘 점점 이 녀석이 군것질에 맛들이고 있다. 큰일이다. ㅋㅋ. 외사촌 누나 영향이 크다.)

제목에는 예방접종 안하는 이유라고 적었지만 사실 끝까지 안할 생각은 없다. 다만 지금 굳이 해야 하나 의심할 뿐이지. 오히려 백신을 통해 예방을 하는 것보다는 우선 몸 자체의 면역력을 올리는 것이 더 중요하지 않겠는가. 백신 접종은 열심히 하면서 먹거리와 자연 치유력에 신경쓰지 않는다면 너무 쉽게 몸을 생각하는 것이 아닌가.

그리고 백신의 위험성에 대한 두려움도 있다. 백신의 위험성에 대해서는 안전한 예방접종을 위한 모임 에서 좀 더 다양한 주장을 읽어 볼 수 있다. 이 사이트에 있는 주장을 믿느냐고 묻는다면 별로 할 말은 없다. 이런 주제는 워낙 양쪽 주장이 첨예하게 부딪치는 문제라 쉽게 어느쪽 주장에 손을 들어 주기는 어렵다. 단지 주장이 문제가 아니라 그 근거를 알려면 의학 및 관련 통계에 대해서도 지식이 풍부해야 한다. 나같은 일개 프로그래머가 머라 주장하기는 좀 힘들다. (하지만 살아보면 느낌이란게 있긴 하지).

그리고 나는 자본(제약회사. 병원. 그에 종사하는 이해관계자들)이 하는 일을 크게 믿지 않는다. 자본은 기본적으로 돈버는 일에만 관심이 있지 선량한 의지는 없다. 문제가 생기면 문제없다고 뻐팅기기만 하고, 결국 문제가 드러나면 슬그머니 후퇴한다. 백신의 역사도 그렇다. 백신의 부작용이 이렇게 알려진 것도 그 누군가의 피눈물과 항의가 있었기 때문이지 그들은 스스로 문제점을 인정하지는 않는다. (혹시 아직도 백신에 수은이 있나 모르겠네). 국가가 하는 일도 마찬가지다. 국가는 기본적으로 자본의 대리인이 아니던가. 국가는 백신 예방접종에만 신경쓰지 말고, 전 국민의 먹거리 안전과 자연 치유력 향상을 위해 더 노력해야 할 것이다. 하지만 그들이 과연 그렇게 해 줄까?

(웬지 제목이 검색에 너무 쉽게 노출될 것 같다. 댓글로 엄청 까일 것 같은 불길한 기분이...)

2012-08-10

스프링 @MVC 수정 폼 처리하기

Spring MVC 3.0: How do I bind to a persistent object

@ModelAttribute의 쓰임새는 무엇인고?

How does @ModelAttribute work?

@RequestMapping(value="/user/{id}", method=RequestMethod.PUT)
public String submit(@ModelAttribute User user) {
   ...
}

@ModelAttribute("user")
User loadUser(@RequestParam(defaultValue="-1") long id) {
    if (id == -1)
        return new User();
    log.info("Loading user info from db: " + id);
    return userService.findById(id);
}

이 코드가 의도하는 것은 @ModelAttribute 가 바인딩 되기 전에 db로 부터 User 객체를 로드하는 것이다. 이렇게 db에서 user를 로드한 다음 바인딩하면, User 필드에는 있지만 폼에는 필드가 없어서 기존 db 필드를 null로 지워버리는 불상사를 막을 수 있다.

문제는 위 코드의 경우 loadUser()가 이 컨트롤러의 다른 메소드에도 실행된다는 것이다. 이건 좀 깔끔하지 못하다. 좋은 방법을 모르겠다. 위 코드만 따로 뽑아서 새로운 컨트롤러를 만들 수도 있겠다. 이렇게 하면 엔티티마다 XxxModifyController 를 만들어야 한다. 이것도 그리 썩 좋지는 않지만 다른 방법이 없네.

ConversionService로도 안될 것 같고. @SessionAttributes를 사용하면 한 세션에 여러 엔티티에 대한 폼을 열 경우 문제가 된다.


update(2012.9.6): 위 해결책도 나름 방법이긴 하지만 ConversionService를 이용하면 된다. 그러나 스프링 3.1이후에서만 된다.