저자: 이아스님(
http://www.iasandcb.pe.kr)
아주 한동안 소식을 못전해 드렸습니다. 그간 있었던 일들을 간추려드립니다.
퍼스널 프로파일(Personal Profile) 1.0 (JSR-62), 무선 메시지 처리(Wireless Messaging) API(JSR-120) 최종안(final draft) 공개
퍼스널 프로파일(Personal Profile) 1.0 (JSR-62), 무선 메시지 처리(Wireless Messaging) API(JSR-120)는 각각 해당
JSR 공식 사이트에 가시면 받으실 수 있습니다(참고, JSR-XXX 공식 사이트:
http://www.jcp.org/jsr/detail/XXX.jsp). 퍼스널 프로파일은 알려진대로 구 퍼스널 자바를 J2ME의 컨피규레이션-프로파일 이원화 정책에 맞게 각색한 것입니다. 따라서 다음과 같은 특징이 있음을 위의 권고안에서 엿볼 수 있습니다.
- 퍼스널 자바와 마찬가지로 AWT(JDK 1.1대의) 중량 컴포넌트 모델을 따르고 있습니다.
- 따라서 그간 퍼스널 자바에서 돌아간(혹은 돌아갈) 애플릿과 애플리케이션을 퍼스널 프로파일로 자연스럽게 이전할 수 있습니다.
- 기묘한 구성: 기본적으로 J2ME CDC-FP 위에 있으면서도 J2SE 1.3.1의 java패키지는 상위 호완성(upward-compatibility)을 가지고 있습니다.
- 3가지 애플리케이션 모델: 기존의 퍼스널 자바가 제공하던 애플릿(Applet), 애플리케이션(main) 방식과 더불어 Xlet이 생겼습니다. MIDP에서의 MIDlet과 유사한 형태의 이 모델은, 역시 PP의 기반 환경인 소형 단말기에 최적화되어 있습니다.
- 이미지 포멧은 GIF, JPEG, PNG 다 지원합니다.
- J2SE와의 다른 점: java.awt의 몇 가지 클래스의 기능에 대한 제약이 걸려 있습니다.
문제는 이런 퍼스널 프로파일을 어떤 단말기들이 구현해줄까 입니다. 팜5 시리즈가 막강한 파워로 CLDC-MIDP가 아닌 CDC-PP를 지원할지, WinCE(포켓PC)에는 MS가 아닌 누가 PP를 올려줄지, 현재 CDC-FP가 팜이나 포켓이 아닌 리눅스 x86용으로 RI가 있다는 사실은 뭔가 석연치 않은 미래를 암시하기도 합니다.
곁들인 뉴스입니다만, CDC-FP RI 1.0.1이 나왔습니다.
http://developer.java.sun.com/developer/earlyAccess/jsp/에 가시면 받으실 수 있습니다. JSP 2.0 Preview EA 1이라는 정식 명칭을 가지고 있는 이 구현체는 흥미롭게도 톰켓 4에 기반하고 있습니다. 순수 개발-테스트용이라는 전제 하에 배포되고 있으며, 다음과 같은 구절을 공개 노트에 담고 있습니다.
"톰켓 5.0판이 곧 서블릿 2.4와 JSP 2.0을 구현하는 제품 품질 수준의 웹 서버를 제공할 것이다."
특이할 만한 점으로는 다음과 같은 사항이 있습니다.
- 제스퍼2 엔진 탑재: 톰켓 4.1대에서부터 달기 시작한 JSP엔진
- JSP 2.0 API 수록: 공개 초안 1판 준수
- 표현식어(Expression Language) 기본 내장-JSTL에서 뿐만 아니라 JSP의 전 구문에서 사용 가능
이밖에도 커스텀 태그와 관련된 JSP 2.0 사항도 대폭 확충되었습니다. 아무튼 궁금하신 분이라면 바로 설치해보는 것이 최고! 그런데 JSP 2.0이 J2SE 1.4를 필요로 하시는 것은 모두 알고 계시죠?
이 JSP 2.0 PI(Preview Implementation)을 띄우면 다음과 같은 콘솔 화면이 나옵니다.
2002-07-23 오후 12:53:40 org.apache.commons.modeler.Registry loadRegistry
정보: Loading registry information
2002-07-23 오후 12:53:40 org.apache.commons.modeler.Registry getRegistry
정보: Creating new Registry instance
2002-07-23 오후 12:53:41 org.apache.commons.modeler.Registry getServer
정보: Creating MBeanServer
2002-07-23 오후 12:53:45 org.apache.coyote.http11.Http11Protocol init
정보: Initializing Coyote HTTP/1.1 on port 8080
2002-07-23 오후 12:53:45 org.apache.jk.server.JkMain init
정보: Starting Jk2, base dir= .. conf=..\conf\jk2.properties
2002-07-23 오후 12:53:45 org.apache.jk.server.JkMain start
정보: APR not loaded, disabling jni components: java.io.IOException: no jkjni in
java.library.path
2002-07-23 오후 12:53:45 org.apache.jk.common.ChannelSocket init
정보: JK: listening on tcp port 8019
2002-07-23 오후 12:53:45 org.apache.jk.common.ChannelUn init
정보: No file, disabling unix channel
2002-07-23 오후 12:53:45 org.apache.jk.server.JkMain start
정보: Jk running ID=0 ... init time=391 ms
Starting service Tomcat-Standalone
J2EE SDK/1.4
2002-07-23 오후 12:54:01 org.apache.coyote.http11.Http11Protocol start
정보: Starting Coyote HTTP/1.1 on port 8080
여기에서 알 수 있는 것은,
- JMX을 기본으로 쓰고 있다.
- 코요테 커넥터를 쓴다.
- J2EE SDK/1.4 !!! - 톰켓 5는 J2EE 1.4 RI의 기본 구성요소이다.
이렇게 띄우고 나서 예제를 확인해보시면 JSP 2스타일의 모습을 미리 보실 수 있습니다. 과연 JSP 2가 막강 자금력+대형 ERP가 선사하는 근사한 분업화를 중소회사와 중소 프로젝트에까지 실현해줄런지... "꿈은 이루어진다"라는 카드 섹션이 기억납니다.
디비독 소개
Dbdoc: PERSISTENCE PAYS라는 기사에서 소개된 dbdoc은 그동안 자바독이 맡아왔던 자바 문서화 기능을 더욱 강화하며 웹에 적합한 사용자 인터페이스와 문서 관리를 가능하게 해주는 멋진 솔루션입니다. 공식 사이트는
http://www.dbdoc.org/입니다.
앤트 팁
저는 요새
앤트(ant)를 통해 자바 웹 애플리케이션 제작 작업을 하고 있습니다. 특히 톰켓과의 연동은 놀라운 정도인데요, install-reload-remove의 개념을 아주 충실히 따르고 있습니다.
그렇긴 한데, 처음 앤트의 자바 컴파일 태스크(task-앤트에서의 단위 작업을 지칭)를 통한 클래스 파일에는 디버그 정보가 없어서, 서블릿이나 기타 클래스에서 예외가 발생한 경우 해당 소스 코드 줄번호를 보여주지 못하더군요.
그래서 앤트 문서를 확인해 본 결과, 앤트의 자바 컴파일 태스크는 기본적으로 디버그용 부가 정보 추가 설정을 off로 하고 있었습니다. 물론 웹 애플리케이션의 설치-배치가 의미하는 것은 실제 서비스를 위한 실행이고, 따라서 클래스에 부가 정보를 넣는 것은 의미가 없는 정도가 아니라 지양해야 하는 것이겠지만, 개발-실험시에는 무척 요긴한 설정임에 분명합니다.
ant를 통해 컴파일할 때 디버그 정보(예외 발생시 소스 코드 줄번호 표시) 지원하려면 아래 보이는 코드에서처럼 debug 속성을 on값으로 설정해주면 됩니다.
<javac srcdir="src" destdir="${build}/WEB-INF/classes" debug="on">
오라클 JDBC 드라이버와 톰켓 4와의 연동 문제
오라클 JDBC 드라이버인 classes12.zip을 J2SE 1.4+톰켓 4.0.4가 잘 불러오지 못합니다(톰켓 4.1대도 마찬가지). 아마도 zip파일을 처리하는 데에서 오는 문제가 아닐까 싶은데요, jar를 통해 묶으면 잘 됩니다. 예를 들어 db 디렉토리에 classes12.zip을 풀어놓고, 아래와 같이 해주면
jar -cvMf oracle-jdbc-driver.jar -C db .
db 디렉토리 밑에 있는 클래스 파일을 패키지명과 함께 잘 살려 묶어줍니다. 이것을 WEB-INF/lib에 두면 되겠습니다.
재밌는 태그 라이브러리
이곳에 가보면 거창하게 말해 서버측 영상 처리, 간단히 말해 서버에서 이미지를 생성하여 브라우저를 통해 출력하는 일을 편리하게 해주는 태그 라이브러리가 있습니다. 그래프나 배너, 혹은 아바타를 동적으로 그려내는 데에 유용하게 사용할 수 있을 것 같습니다. 이 태그 라이브러리의 제공사인 콜드빈즈(Coldbeans) 소프트웨어는 이밖에도 매우 흥미로운 다수의 서블릿-JSP 관련 기술을 보여주고 있습니다. 비상용(非商用, non-commercial)-비공용(非公用, non-government)인 경우에는 모두 무료라는군요. URL을 알려주셨던 OKJSP의 케누님께 감사드립니다.
그동안 제 야후 노트에 묶혀두었던 자바 팁들을 공개합니다.
콤보박스(JComboBox)의 setSelectedIndex 메소드는 콤보박스에 부착되어 있는 ActionListener의 actionPerformed를 연쇄 호출합니다. 즉 사용자가 조작하지 않아도 프로그램 내에서 콤보박스 인스턴스의 setSelectedIndex를 호출하면 actionPerformed도 따라서 불리는 것이죠. (작년에 스윙 프로젝트를 하면서 발견한 것인데 이제서야 빛을...)
메소드의 매개변수가 final로 선언되어 있다는 것은 무슨 의미일까요? 예를 들어
public void process(final int data)
{
...
}
과연 이런 매개변수 목록 정의가 가능한지조차 의심스럽지만, 잘 되고도 그 쓰임새가 있습니다. 바로 위의 메소드절 안에서 무명 클래스를 쓸 경우 무명 중첩 클래스절 안에서 그 클래스를 중첩하는 클래스의 파이널 변수만을 접근할 수 있기 때문이지요. 구체적으로 예를 들어
public void process(final int data)
{
...
어떤 중첩 무명 클래스... 시작
{
System.out.println(data);
}
...
}
어떤 홈페이지에서 다른 홈페이지로 바로 돌려주려면? 재지정(redirection)이라고 고상하게 말하는 기능을 HTML의 메타 태그로 해낼 수 있습니다.
쉽지만 "개똥도 약에 쓰려면 없다"고, 기억이 잘 안날 때도 있지요.
아파치를 깔고 나면 기본 설정으로 URL이 디렉토리인 경우 그 디렉토리에 포함된 파일들의 목록이 나옵니다. 물론 편할 때도 있지만, 감추고 싶을 때도 있지요.
디렉토리에 DirectoryIndex로 설정된 index.html 등이 존재 하지 않을 경우 기본설정은 디렉토리 안에 들어 있는 목록을 출력하게 되어져 있습니다만, 출력을 원치 않으실 경우에는 DocumentRoot 디렉토리 쪽에 설정되어져 있는 옵션에서 Indexes를 지워주시기 바랍니다. 특정 디렉토리에서만 인덱스를 허용치 않을 경우에는 특정 디렉토리의 .htaccess 파일 안에 다음과 같이 추가하여 주시기 바랍니다.
Options -Indexes
신간 소개
오라일리에서
『Java NIO』라는 책이 나와있습니다. 그간 Java I/O가 자바 I/O계의 바이블이었던 고로 그 후속탄이 안나오나 했는데, 이렇게 별책으로 나오네요. 약 300페이지의 가벼운(이 바닥에서는) 모습으로 나올 예정입니다. 번역도 계획되어 있다니 한두 달 기다리시면 되겠네요.
JSP 2.0 - 인코딩 소개
이제 서블릿 2.4 최종 제안 초안까지 나오고, 여름이 다 가고 가을이 올 즈음 나올 J2EE 1.4의 모습은 점점 윤곽이 잡혀 가고 있습니다. 여기서 JSP 2.0의 특별한 개념을 하나 소개할까 하는데요. JSP 2.0 규격 문서(공개 초안 기준)의 78쪽(JSP 3.3.4)을 보시기 바랍니다(PDF파일에서는 111쪽입니다.)
현재 이 JSP 설정에 대해 서블릿처럼 web.xml과 같은 배치 설명서에 쓸 지, 아니면 따로 설정 설명서를 쓸 지는 JSP 2.0 책임 전문가 모임에서 궁리중이라고 합니다만, 아무튼 JSP페이지에 일괄적으로 인코딩 설정을 할 수 있다는 것은 무척 편리하다 하지 아니할 수 없습니다.
그런데, 과연 페이지 인코딩이라는 것이 정확히 무엇을 의미하는 것일까요? 흥미롭게도, JSP페이지는 자체가 하나의 텍스트 파일이므로, 문자 인코딩을 가질 수 있습니다. 그런데, 그 JSP페이지가 출력하는 HTTP 응답 메시지도 문자 인코딩을 가질 수 있죠. 이렇게 JSP 파일 인코딩과 JSP 응답 인코딩의 근본적인 이원적 양립은 JSP 저작자를 무척 혼란스럽게 만듭니다. 아주 극단적인 예를 들어, JSP파일은 EUC-JP이면서도 JSP응답 출력(즉 브라우저에 나타나는 텍스트)은 EUC-KR일 수도 있다라... 쉽게 상상은 안가지만 의외로 국제화-지역화의 걸림돌이 되기도 합니다.
그래서, 문서에서 "4장, 지역화 문제"를 보면 이에 대해 자세히 써놓았습니다. 표 JSP 4-1을 보면 무척 명백한데요, 간단히 정리하면 JSP 소스 인코딩과 출력 컨텐트 인코딩을 encoding과 contentType이라는 페이지 지시사 속성으로 따로따로 설정할 수 있으며, 다만 contentType이 따로 설정되지 않은 경우 encoding의 설정으로 한다는 것입니다. 예를 들어 아래와 같이 하면
<%@ page encoding="EUC-KR" %>
톰켓에서는 기본 contentType을 text/html이라고 가정하므로 contentType="text/html;charset=EUC-KR"과 같이 잡아주게 된다는 말입니다.
"음... 그러니까 앞으로는 페이지 인코딩만 잘 잡아주면 (한글) 문제는 없겠구나..."
이런 설정은 사실 JSP관련 웹 저작 도구(예를 들어 드림위버)를 위한 느낌도 없지 않아 있습니다. 아무튼 점점 더 지역화-국제화 신경써주는 JSP와 서블릿에 기분 나쁘지는 않네요.
푸념-모바일계의 각종 약어들
LIF, MLP, 3GPP, GSM, GMLC, SIG ... 이 약어들이 다 무슨 말을 줄인 것이고, 그 뜻이 무엇인지 헤아리실 수 있겠습니까? 이렇듯 난무하는 영어 약어들의 발음 또한 외국인인 우리에게는 쥐약일 따름이죠. (더 혼란스러운 것은 영어를 모국어로 하는 사람들조차 발음들이 미묘하게 다르다는 것입니다. T_T)
아무튼 이런 약어를 인터넷으로 검색해보면 잘 나오니까 걱정은 덜하지만, 실시간으로 새로운 약어를 들을 때의 당혹감은 참으로 지우기 어렵습니다. 그러고보니 최근에 이통사들도 이름을 모두 영어약자로 바꿨군요. SKT, LGT, 그리고 가장 드라마틱하게 바꾼 곳은 한국 통신 프리텔의 "KTF"변신. 그런 이름들을 듣고 있노라면 왜 작년에 죽으라고 일본에서 보았던 NTT가 생각나는지. 그 옛날 옛적 장학 퀴즈때의 선경과 럭키금성(영어로는 골드스타!), 한국 통신이 조금이나마 그리운 것은 저혼자만의 단상인가요?
옛날 서블릿 이야기
비도 오고 하니 옛날 얘기가 계속되는군요. 최근 저는 몇 통의 질문 메일을 통해 희한한 사실을 알았습니다. 그것은 바로
"아직도 서블릿 2.0으로 공부하는(혹은 개발하는) 사람들이 있다!"
였습니다. 그 배경에는 JServ의 건재함이 있는데요, 아직까지도 아파치와 함께 서블릿 연동을 위해 JServ를 쓰는 곳이 있나 봅니다.
살짝 미소(^^) 짓는 시간도 잠시, ServletContext가 서블릿의 배치 설명서(일명 web.xml) 개념의 도입과 함께 많이 변하면서, 새로운 메소드가 추가되었는데 당연히도 서블릿 2.1이상이어야 하죠. 요새 책들은 이런 상황을 당연시 하지만, 2.0이하만을 지원하는 JServ에서는 "천만에 말씀 만만의 콩떡"이고, 분명히 책에서는 잘 된다고 했건만 실제 컴파일도 실행도 안되면 답답하다 못해 깝깝하죠. (다시 미소 ^^)
이와 비슷한 예화 중에 폼 텍스트 빈 필드가 요청으로 넘어올 때 null이냐 공백 문자열이냐의 헷갈림도 유명합니다. 지금이야 서블릿 규격 표준 구현체인 톰켓이 request.getParameter에서 해당 이름의 폼 필드가 없을 때는 null, 있지만 아무 값도 입력하지 않았을 경우에는 ""으로 넘겨주어 세상이 다 편해졌지만, 예전에는 어떤 컨테이너는 null, 어떤 컨테이너는 "", 심지어 같은 컨테이너안에서도 동작이 오락가락... 이런저런 것 다 좋지만 가장 짜증나는 필수 조건문인
String name = request.getParameter("name");
if (name == null) name = "";
을 안써도 되는 세상이 왔다니... 다시 생각해보면 참으로 격세지감(1999년 9월 -> 2002년 8월) 그 자체입니다.
옛날 서블릿 이야기하자면 그 속상하고 말도 안되는 사연들을 소설책으로 써도 모자라겠지만, 세월은 역시 기다린 보람이 있어 오늘날과 같이 정형화된 서블릿 규격과 구현체의 등장이 더 이상 고마운 일도 아니게 되어버렸답니다.
그러나, 아직도 서블릿 규격의 모자람과 톰켓의 불안함을 탓하는 이가 있으니(아마도 많으니), 기다림은 그들의 불만을 잠재우겠지만, 또다른 불만도 함께 지필 거라 머릿속으로 그려보면 참으로 서블릿 소우주도 "요지경"입니다. 요지경!
MIDP 스타일 프로그래밍?
제목은 좀 황당하지만, 정말로
이 링크를 눌러보시면 그런 문서가 나옵니다. 아마도 MIDP 프로그래밍의 전범을 보여주고자 한 문서 같은데, 글쎄요... 아직 완성본은 아니랍니다. 앞으로 더 좋은 보충과 진행 있기를 기대해봅니다.
URLEncoder.encode(String)이 비추천이라고?
아무 생각없이 서블릿에서 java.net의 URLEncoder.encode(String)를 써서 컴파일을 하니 난데없는 비추천(deprecated) 경고가 떠서, 그동안 잘 써왔는데 무슨 소린가... 해서 조사해본 결과,
실로 놀랍게도 JDK 1.3까지는 잘 쓰이던 URLEncoder의 encode(String)가 JDK 1.4에 와서는 문자 인코딩 인수가 첨가된 encode(String s, String enc)를 추천하고 있습니다.
게다가, 그 인코딩이라고 하는 것도
"W3C에서는 UTF-8을 추천하고 있고, 안그러면 호환성에 문제를 야기할 수도 있다."면서 겁주고(?) 있습니다. 음... 이는 아마도 MS IE의 고급 설정 중 "URL을 항상 UTF-8로 보냄"과 관련이 있을 것 같은데... 아무튼 갑작스레 바뀌어서 혼란스럽기는 하군요.
정리하면, JDK 1.4이상을 쓰시는 분들은 썬과 W3C의 권고를 받아들여 인수 두 개짜리 encode를 쓰시고, JDK 1.4미만을 위한 프로그램에서는 기존의 encode를 그대로 쓰시면(쓰셔야) 되겠습니다.
JSP의 getProperty, JSTL의 c:out 그리고 문자열 null과 ""값의 애증
먼저 톰켓과 OC4J(오라클iAS)과의 처리 차이를 보겠습니다.
예를 들어 SubjectBean item에 name이라는 필드가 있어 null값을 가지고 있는데 JSP에서
A
B
하면 톰켓은
AB
와 같이 ""으로 표시하고
OC4J는
AnullB
와 같이 "null"로 표시합니다.
왜 이런 차이가 벌어지는 걸까요? 이는 규격과 구현을 구별하고 있는 자바 표준 기술의 한 단면을 보여주고 있습니다. 실제 JSP 1.2(2.0) 규격 문서에는
태그에 대해서, property의 출력을 out.println()으로 처리한다고만 정하고 있어서, String name = null 인 경우 out.println(name) -> "null"로 찍히는 것을 막고 있지 않습니다. 다만, 톰켓이나 여타 웹 컨테이너에서 이런 보기 좋지 않는 출력을 나름대로 걸러주어서 null인 문자열의 경우 ""으로 대체하는 것이죠.
이런 상황은 이미 어제 소식에서 고백했던 서블릿의 request.getParameter에서도 마찬가지입니다. 서블릿 규격에서는 해당 이름의 요청 매개변수가 없으면 null을 반환하라는 말만 있을 뿐, 해당 이름의 요청 매개변수가 있되 값이 없는 경우에는 null을 반환하라, 혹은 ""을 반환하라는 정확한 언급을 하지 않고 있습니다.
위와 같은 정황이, 규격을 최소한으로 기술을 규정하고, 구현자에게 최대한의 자유를 주기 위한 것인지는 몰라도, 사용자의 입장에서는 그닥 기분 좋은 자유처럼 느껴지지는 않는 식이죠.
그런데, JSTL의 태그는 좀 다른 모습을 보여줍니다. 해당 문자열의 값이 null인 경우 ""으로 출력하라는 문장을 명시하고 있으니까요. 과연 이러한 변화가 서블릿과 JSP에 거꾸로 반영이 될런지는 미지수이지만, 사용자의 불편에 귀기울여 세심한 배려를 하는 쪽이 수백수천만원을 받고 소프트웨어를 파는 회사가 아니라 무료로 공개하고 있는 단체라는 것은 참으로 아이러니 정도가 아니라 의미심장합니다.
덧붙이는 말
어떤 분이 그런 말씀도 하시더군요. 톰켓이 아무리 좋아도, 회사는 예산을 부풀려야하기 때문에 비싼 WAS를 여전히 살 것이다... 글쎄요... 예산을 부풀려 자신이 속한 부서의 존재감을 높이기에는 현재의, 그리고 앞으로의 경제 상황이 썩 좋아보이지는 않군요. 어쩌면 그 필요성에 대해서는 누구보다도 소비자인 법인 고객들이 잘 알고는 있는데, 문제는 선입견과 고정관념이겠죠. 그러나 문제는 의외로 쉽고 빨리 풀릴 수 있을지도 모릅니다. "소비자"는 우리의 상상보다 훨씬 영악하니까요.