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

2010/03/25

Jetty embedding from scratch

0 comment(s)

이클립스 웹 프로젝트시 WTP 톰캣을 사용하는 것이 너무 번거로워 Jetty DSL 을 사용해보기로 하였다. 연습 삼아 maven2 를 사용하지 않고 수작업으로 진행해 보았다.

우선 jetty 를 받아 보았는데, distribution 버전을 받아 보니 뭔가 매우 복잡하다. 경량이라고 하는데 패키지 크기도 그렇고, 파일 숫자도 그렇고, 별로 경량일 것 같다는 생각이 들지는 않는다. 어쨌거나 *.jar 들 중에 그럴듯한 이름을 가진 것들을 이클립스 프로젝트 라이브러리에 올려가며 동료가 제시한 DSL 을 작성해 보았다.

천신만고 끝에 DSL 에 의한 내장 웹서버 실행은 되었는데, 이건 좀 아닌듯 싶었다. maven 과 tomcat 사용이 번거로워 해 본 일인데, 이렇게 복잡하게 라이브러리 임포트를 한다면 차라리 maven 이 낫겠다 싶었다. 그러다가 문서를 다시 한 번 살펴보니, Jetty HelloWorld Tutorial 에 jetty-all-${VERSION}.jar 를 받아 적용하는 방법이 나와 있었다. 결국, jetty-all 과 servlet-api.jar 두 가지만 라이브러리 의존성에 포함시켰더니 간단하게 웹서버 실행이 가능하게 되었다.

그런데, JSP 지원이 빠져 있다. Jetty 7 부터는 JSP 를 기본적으로 지원하지는 않는다고 한다. 어차피 원하는 바이긴 했지만 당장은 JSP 를 쓸 필요가 있었기에, 조금 더 살펴 보니까 jsp-2.1 과 jsp-api-2.1 을 가져와야 한다고 한다. 이들 라이브러리는 glassfish 에서 표준화된 것들이라고 하는데, 삽질 끝에 결국 기존 jetty 6.x 대 버전에서 jsp 관련 라이브러리들을 가져와서 해결했다. 해결 이후 보니, 해당 라이브러리들을 *.jar 로 착각했었는데, 디렉터리였고 그 안에 조금 복잡하게 jsp 처리 관련 라이브러리들이 들어 있었다.

결국 jsp 를 사용하지 않을 경우 굳이 maven2 같은 빌드 툴을 사용하지 않고도 쉽게 구성이 가능한데, 그냥 maven jetty plugin 을 사용하는 것이 현재까지는 가장 편한 방법인 것 같다.

2010/01/12

왜 그들은 JSTL/커스텀태그에 집착할까?

2 comment(s)

Java Web Application 을 구현하다 보면 항상 사람을 피곤하게 하는 부분이 HTML 쪽 처리이다. 어째서 JSTL/커스텀태그 만을 사용해야 하는지 납득할 수 없다.
기본 루프식도 마음에 안들고 if - (else if -) else 를 지원하지 않는 것도 마음에 들지 않지만(태그 구조상 지원할 수 없는 것이 당연하기는 하다) 파라메터가 있는 메소드를 사용할 수 없다는 점은 정말 최악이다. 이 것 때문에 서버 측 코드 설계까지 좋지 않은 영향을 미친다.

JSTL 에 맞추려고 서버 측 코드 설계를 제대로 할 수 없는 것은 핑계일지도 모른다. 그렇다고 그런 코드를 처리하기 위한 커스텀태그를 만드는 일도 좋지 않다.
단지 출력하는 부분을 처리하기 위해 커스텀태그를 만드는 것은 상당히 귀찮은 작업일 뿐만 아니라 배보다 배꼽이 커지는 작업이기도 하고, 이런 특수한 코드 - 보통 JSTL 로 처리할 수 없는 내용은 독특한 기능이 대부분이다 - 를 처리하기 위해 커스텀태그를 만드는 것 자체가 더 안 좋다. 코드와 커스텀태그가 항상 종합선물셋트로 묶여 같이 붙어다녀야 한다. 재사용성 최악이다. 단지 특수 코드를 억지로 태그 표현식으로 나타내기 위해 하는 커스텀태그 구현을 뭐하러 해야 할까? 그런 태그는 만들어 놓은 사람도 훗날 그 사용 방법을 기억해 내기가 쉽지 않다.
결국 재사용성 높은 태그로 처리하게 하려면 기본적인 Map/Set/List 자료형으로 구현해야 하는데 정작 그렇게 범용성을 부여하기가 쉬운 것도 아니고 막상 만들고 나면 그런 커스텀태그는 대체 어디에 어떻게 사용하기 위한 것인지 애매모호하게 되기 쉽다.

"매우 간단한" 목록형은 JSTL로 간결하게 표현할 수 있다. 그런데 이는 스크립틀릿도 마찬가지 아닌가? 오히려 복잡한 표현식은 스크립틀릿이 더 자유로울 뿐만 아니라 무엇을 하는 것인지 파악하기도 쉽다.
스크립틀릿을 쓰면 가독성이 떨어진다? 말도 되지 않는 소리이다. JSTL 을 쓴다고 가독성이 좋아지지 않는다. 애초에 쓸데없이 복잡하게 만든 HTML 페이지 디자인 자체가 문제다. 브라우저가 무슨 유화를 그리기 위한 캔버스도 아닌데 말이다.

2010/01/08

색인을 만들기 위한 한글 자소 단위 분해

0 comment(s)

프로젝트에 주어진 과제 중 책 찾아보기처럼 가나다 순으로 제목을 모아 놓아야 하는 기능이 필요하게 되었다. 영문이나 숫자는 그냥 첫 글자만 식별하면 되었는데, 한글인 경우 그렇게 단순하지가 않았다. '가', '거', '객' 등을 모두 'ㄱ' 이라는 대표문자로 묶어야 해서, 일단 한글인 경우 첫 글자를 초/중/(종) 으로 분해해서 초성으로 식별을 하는 방식을 사용했다.

source


test case

2009/12/13

public method 변경하기

0 comment(s)

일하던 중 동료 하나가 말을 걸어 온다. 어느어느 프로젝트에서 에러가 나고 있다고. 내가 손대지도 않았는데 왜 나한테 이야기를 할까?

최근에 이런 일들이 몇 번 있었다. 그렇다고 팀원들이 정말 몰라서 그러는 것은 아니다. 오히려 그런 잘못이라면 이 프로젝트에서는 내가 처음 저질렀던 것 같다(하지만 모를 일이다).

수많은(실은 몇 안 되는) 명저들에서 본 내용 중 하나가 public method 는 함부로 고치지 말라고 했다. 혹은 신중을 기하라고 했던가. 그런 내용을 접하기 전 까지 별로 생각해 볼 수 조차 없었을 내용들인데 읽고 나서는 너무나 당연하게 생각되는 내용이라 당연히 잘 할 것이라 믿었었는데 나도 그렇고 동료들도 그렇고, 치명적인 실수를 저지르고 말았다.

동료 A 는 해당 기능을 하는 method 를 더 효율성이 높은 것으로 대체한다고 기존 것을 지웠다. 물론 본인은 충분히 확인을 한다고 하였겠지만, 문제는 그 class 가 구현된 main 프로젝트가 아니고 다른 sub 프로젝트에서 해당 method 를 참조하고 있어서 발생했다.
동료 B 는 단순히 메소드 이름을 변경하는 refactoring 을 했는데, sub project 에 그 변경이 반영되지 않았다. 상당히 신중하고 시야가 남다른 B 였기에 조금 의아했지만 결국 public 메소드에 대한 변경이 그만큼 단순한 일이 아니라는 증거일 것이다.

다들 잘못이라면 잘못을 하긴 했는데 온 세상에 널리 퍼뜨린 라이브러리도 아니고, 범위가 명확한 프로젝트 안에서 다른 참조 프로젝트에 그 변경이 반영되지 않았다는 것은 지금 쓰고 있는 eclipse 잘못인지, 너무 복잡하게 얽혀 있는 지금 프로젝트 잘못인지 모르겠다.

2009/06/08

32bit JVM java.net.UnknownHostException

0 comment(s)

어떤 테스트케이스를 실행하는데 자꾸만 test error 가 발생한다. fail 이 아니고 error. 나는 아무것도 바꾸지 않았는데... 사실 바꾸긴 바꿨는데, 전혀 상관없는 부분에서 에러가 발생한다. ESMParserTest 라는 곳이다.

어찌 되었건 무엇 때문에 에러가 발생하는지는 알아야 해서 찬찬히 살펴보았더니, UnknownHostException 이다. 왜일까? 표준 DNS 에 등록해 놓은 호스트인데.
/etc/hosts 파일 안에 해당 도메인과 IP 주소를 매핑해 놓았더니 더 이상 에러가 발생하지 않는다.
이렇게 해결하는 것은 근본적인 해결책이 아니다. 그럼 대체 왜 발생할까?

GWT 플러그인이 64bit linux 용은 아직 없어서 32bit JVM 을 지정하여 사용하고 있는데 32bit JVM 에서 에러가 발생한다. 그렇다면 M$ 의 32bit JVM 에서는 왜 에러가 발생하지 않고 잘 돌아갈까? 한 번 64bit JVM 에서 테스트케이스를 돌려 보니 정상적으로 통과한다.
이럴수가. 어떻게 한군데씩 꼭 문제가 있을까?

슬프게도 역시 M$ 에서 개발을 해야만 하는 것일까? 모처럼 힘들여 64bit 환경에서 안 되는 GWT 개발을 32bit 로 맞추면 되기에 불만스럽지만 겨우 적응해 나가고 있었더니 새로운 문제가 발목을 잡는다.

2009/03/30

JSPWiki 설치 시작

0 comment(s)

내가 멍청한 것인지 애초부터 프로그램이 잘못된 것인지 잘 모르겠지만 상당한 삽질 끝에 일단 띄우는 데 성공했다.

우선 톰캣 webapps/ 아래 .war 파일을 풀어 놓았다. 나중을 생각해서 $CATALINA_HOME 이 아닌 $CATALINA_BASE 를 따로 두어 $CATALINA_BASE/webapps/ROOT 아래 JSPWiki.war 파일을 풀어 두었다.

그 다음, $CATALINA_BASE/webappas/ROOT/WEB-INF/jspwiki.properties 를 열어 다음 세 곳을 편집한다.

jspwiki.fileSystemProvider.pageDir = $DATA_PATH/
jspwiki.basicAttachmentProvider.storageDir = $DATA_PATH/
log4j.appender.FileLog.File = $DATA_PATH/jspwiki.log
$DATA_PATH 뒤에 /를 꼭 붙여야 하는지는 아직 잘 모르겠다. (뒤에 언급하겠지만 이게 다는 아니다.)

이 상태에서 서버를 띄운 후 http://localhost:$PORT/Install.jsp 를 실행한다. 몇 가지 설정 사항을 입력하고 [Configure] 링크를 누르면 설정 완료창이 나오는데, 여기에 admin 계정과 암호가 나온다. 찾기 정말 힘들게 해 놓아서 조금 그렇다.

이후 다시 서버를 내렸다 올려야 한다는데 조금 이상하지만 시키는대로 하고 났더니 로그인하려니까 404 나오고 난리도 아니다. 주소에 JSPWikiLogin.jsp 가 나오는데 실제 찾아보면 이런 파일이 없다. 찾아 보니까 jspwiki.properties 에서

jspwiki.baseURL = wiki/
이런 식으로 되어 있는 것을 (내 경우 주석 처리되어 있었던 것도 같다.)
jspwiki.baseURL = http://localhost:8180/JSPWiki/
이런 식으로 바꿔 줘야 한다고 되어 있다. 나는 http://localhost:8080/ 이라 해 주었다.

이렇게 해 놓고 서버를 다시 시작하니 잘 동작한다.

아직 해야 할 것들은...

  • 왜 war 를 풀어 놓고 설정을 건드린다음 시작해야 제대로 되는가?
  • tomcat startup.sh -Dcatalina.base=$CATALINA_BASE 옵션은 왜 안 먹는 것인가?
  • context path 지정
설치 문서를 보면, 이미 간단한 애플리케이션 단계를 넘어서서 괴물(과장이겠지만... 공감한다)이 되었다고 하는데 고쳐 나가며 사용이 가능할 지 모르겠다.

2008/09/04

스트럿츠2 액션 개발 중 했던 바보짓 #1

0 comment(s)

이런 내용은 바로바로 올렸어야 하는데, 역시 시간이 지나니 기억이 희미해진다.

한 1주일 쯤 되었던가...

스트럿츠2의 액션을 안다면 - 사실은 굳이 스트럿츠가 아니라 해도 - 다음 코드를 보면 어디를 잘못했는지 바로 알 수 있을 것이다.


저런 식으로 만들고 나서 NullPointerException 을 보게 되었고, '머리를 안 쓰는' 테스트 기반으로 작업하고 있었기에 디버거를 돌려 보니 getRequired() 를 호출할 때 필요한 어떤 멤버 필드가 null 이었다.

auto wiring 인지 setter/getter injection 인지 뭔지 사용되는 용어는 모른다 해도, 얼핏 들은 스트럿츠2의 액션이 작동하는 방식을 주의깊게 생각해 보면 저 코드는 왜 잘못 만든 것인지 알 수 있을 것이다.

프레임워크에서 액션을 초기화할 때 setter 들을 호출하여 여러 가지 상태를 설정할 것이지만 그 순서는 예측할 수 없다. 즉, 위의 코드에서 경우에 따라 springRepositorynull 일 수도 있고 아닐 수도 있다. 우연히도 저 코드에서는 null 이 아니었지만 결국 다른 무엇인가 중요한 것은 null 이었다.

다행히 처음 코드를 작성하고 테스트케이스를 돌려 보던 시점에서 에러가 발생했었다. 만일 저 상태로 작동을 했었다면 오류를 모르고 넘어갔을 것이고 훗날 치명적인 문제가 생겼을 지도 모를 일이다.

결론은 setter 는 엄격하게 객체 상태를 초기화하는 역할만 담당하게 하고 getter 사용은 확실하게 setter 호출이 다 완료된 시점, 즉 execute() 등의 메소드에서 사용해야 한다는 점이다.

그래도 상당 기간 개발을 해 왔는데 아직도 이런 실수를 하다니 아직 가야 할 길이 멀었다.

2008/04/04

Mac OS X 상에서 자바 기반 웹 개발환경 설정 완료

0 comment(s)

오늘 개발환경 설정을 완료하였다. 

개발 환경 자체야 자바 기반에 이클립스를 사용하는 것이니 맥이라고 특별히 문제될 것이 없었지만 로컬에서 작동 테스트를 하기 위해서는 회사에서 만든 아파치모듈이 작동되어야 한다. 해서 이는 가상 머신으로 리눅스를 돌리고 그 안에서 아파치를 실행하는 것으로 해결하였다.

그 동안 설치한 내역이다.

  • Eclipse (europa)
  • Java 6 Developer Preview 9
  • MySQL 5.1 GA
  • VMWare Fusion
  • ubuntu 7.04 server + apache 2.2
  • FireFox 3.x beta
  • Tomcat 6

그 동안 리눅스 및 M$ Windows 에서 각종 가상화 프로그램을 돌려 보았지만 매킨토시 호스트만큼 빠르고 안정적인 경우를 경험하지 못했다. 우선 가상화 운용 환경이 매우 만족스러웠다. 회사 내부 프로그램상 어쩔 수 없이 윈도우XP도 하나 가상 머신으로 돌리고 있는데 그다지 부하가 느껴지지 않았다. 리눅스 서버 및 테스트용 리눅스 데스크탑, 이렇게 세 개의 가상 머신이 작동하고 있는데 체감 속도가 별로 떨어지지 않는다.

이클립스는 UI가 매우 깔끔하여 보기가 좋습니다.특히 기본 글꼴이 매우 마음에 들었다. 아직은 코코아가 아닌 카본 기반이라는 것이 조금 아쉽지만 언젠가 나아지겠지 싶다.

로컬(호스트)에서 작동하는 톰캣과 가상 머신의 웹 서버를 프락시 연동하여 프로젝트 어플리케이션이 작동하는 것을 확인하였다.

남들 다 사용하고 있는 플랫폼을 버리고 모험을 걸었었는데 다행히 애플 노트북이 값비싼 장난감으로 전락하는 일이 발생하지는 않을 것 같다.