hacking/java2009/05/18 22:34
크리에이티브 커먼즈 라이선스
Creative Commons License
오늘은 오랜 만에 개발 관련 포스팅을 가장한 투덜투덜.
뭔가 기술적인 내용을 기대했다면... 낚인거다.

구글 앱엔진이 자바를 지원하게 됐다는 소식은 꽤 오래된 얘기. 그동안 여유가 없어 못본척 넘어가다가, 지난 주에 짬을 내서 삽질을 좀 했다.

일단, 헬로월드... 훗~ 잘되네~ 속도도 짱 빠르고, 이클립스 플러그인도 있으니 금상첨화~ 오오~ 이거! 날로 먹는 톰캣 호스팅 서비슨가? ^O^ 그러나, 섣부른 판단은 금물. 고수일 수록 칼은 조심스럽게 고르는 법... 흠흠... 좀 더 그럴싸한 걸 만들어 보자. 뭘 만들까... 고민하다가 예전에 만들다 말았던 녀석을 옮겨 보기로 했다. (기대 만땅)

제대로 할려면 맥가이버칼(메이븐)이 필요한데... 흠흠... 구글 이클립스 플러그인이 만들어주는 프로젝트의 디렉토리 레이아웃을 보니... 대략 난감. 나중에 좀 더 찾아보기로 하고, 패스 ~.~ 구글링 좀 해보면 알겠지만 나름대로 어수룩한 해법이 있긴 하다. (쉽게 포기)

ORM은 앱엔진에서 제공하는 (JDO 비스므리한) 녀석을 쓰면 되고... 일단, 스프링부터 추가하자. 그러나 1분도 안되 터져나오는 괴성~ 이 뭥미! 스타트업도 안되네. -,.- 거의 무조건 반사로 구글링~ 안되는게 정상이지만, 이러케 저렇게 요로케 조로케~ 조금만(?) 삽질하면 돌아가긴 한다는 군. 하긴... 이런걸 클라우드 위에서 돌리려면 뭔가 제약이 있을 수 밖에 없지... 꽁짜! 톰캣 호스팅 서비슨데... 이정도는 감수해야쥐 ~.~ (미련 둔탱)

그래도, 구글에서 만든 쥬스는 돌아가겠지... 라고 생각하고 후다닥~ 이것 저것 바꿔 봤지만 -.-; 천만의 말씀 만만의 콩떡. 역시 무조건 반사로 구글링 한 결과, 쥬스 최신 스냅샷 버전을 받아서 이러케 저렇게 요로케 조로케~ 조금만(?) 삽질하면 대충 돌아가긴 한다는데... (내가 뭔가 엄한 삽질을 하고 있는게 아닐까...) IoC 컨테이너라는게 첨엔 번거롭고 거추장스럽고 귀찮지만, 있다가 없으면 정말 갑갑한데... 그래도 어쩌랴... 일단 그게 중요한게 아니지! 목표에 집중하자! 집중~ 이렇게 속으로 외치며~ (근거없는... 홧팅!)

jersey를 추가하기로 하고, (메이븐이 없으니 이런 *삽질을...) 여기저기 돌아다니며 관련 jar들을 받아서 추가... 예전에 만들었던 코드에서 DAO만 살짝 바꿔치고 실행하니~ 이건 또 뭥미! ㅠ.ㅠ 다시 구글링... JAXB는 쓸 수 없다는 군 -.-; 뭐 어쩌라는 거냐! (버럭) 뭐 괜찮아... json으로 바꾸면 되지~ (대충 대충)

jettison을 추가하고 다시 이것 저것 뜯어고치기 시작. 흠... JAXB가 안되니 StAX는 당연히 안될꺼고... 그냥 단순무식하게 JSONObject로 만들어서 무식하게 toString()... 이렇게 할꺼면 jersey 쓰는 보람이 없는데... 투덜투덜... 뭔가 더 깔끔한 방법이 있겠지. 내가 GAE/J를 잘 몰라서 그런 걸꺼야~ (구글 만쉐)

오호! 된다 된다!

...

흐뭇한 마음으로 appengine에 프로젝트를 생성하고, 디플로이~~ 했으나... 끝도없이 쏟아지는 경고와 에러들...ㅠ.ㅠ appengine에 만들어진 프로젝트는 삭제도 못하는데... ㅠ.ㅠ "도대체 되는 게 뭔거냐! 그거 먼저 말해줘라!"라고 투덜거리며, 다시 구글링... oTL
구글링할 필요도 없었다. 앱엔진 자바 사이트에 예쁜 이름을 가진 페이지가 하나 있다: JRE Class White List... 이걸 이제서야 보다니... (RTFM)

애초에 블랙리스트 같은 건 없었다. 왜냐 하면 되는 것만 적는게 더 짧으니까... -,.-

물론, maven 없다고, spring 없다고, guice 없다고, jersey 없다고, JAXB 없다고, *없다고... 자바 코딩이 안되는 것도 아니고, 웹 서비스를 못 만드는 것도 아니다. 게다가 구글링 조금만 열심히 하면 나름대로 해결책도 있고, 꼼수도 있고... 그래! 문제는 이거다! 왜 그냥 자바에선 안해도 되는 꼼수를 남발하게 만드는 거냐? 구글 앱엔진에서 돌아가게 만든답시고 엄한 패치를 양산하게 만드는 거냐? (책임 전가)

예전에 마이크로소프트가 Swing 대신 DirectX를 집어 넣고 Visual J++이라는 불세출의 IDE와 함께 배포했던 MSJava를 기억하는가? 나는 그 J++로 수십만줄의 코드를 만들었었다. 그 덕분에 내 자바 실력이 얼마나 늘었는지 모르겠지만, 그 이후로는 MS의 개발자용 제품을 쓰지게 되었다. 지금 구글이 하는 짓을 보고 있노라면 그 때의 MS가 생각난다. (논리 비약)

구글은 이 따위로 만들어놓고 자바를 지원한다고 하면 안된다. 공짠데, 그 정도면 감지덕지라고? 그러니까 자바를 지원한다고 하지 말라고... -,.- 아직 "Early Look"인데 이해하라고... 그러니까 자바를 지원한다고 하지 말라고... -,.- 그랬으면 전세계의 수많은 자바 고수들이 한푼 값어치도 없는 엄한 삽질(내가 jersey에서 json을 뿌리기 위해 한 삽질같은... 값어치 없는... 그런 삽질)하느라고 시간을 낭비하지 않을 꺼 아닌가. (거짓 걸룐)

메일링에서 누가 그러더라. "이걸 Goole AppEngine for Java (GAE/J)라고 부르지말고 Guava라고 부르자"고...여기도 +1 한 표 추가!

이렇게 말하면서도 공짜 톰캣 호스팅(혹은 Django 호스팅)의 유혹을 뿌려치기란 쉽지 않다. 뭔가 낚시에 걸리지 않고(이미 걸렸나?) 떡밥만 쏙~ 빼먹는 방법은 없을까~ 궁리 중... -,.- (무전유죄 유전무죄)

Posted by iolo
hacking/java2009/01/18 01:17
크리에이티브 커먼즈 라이선스
Creative Commons License
JDBC 코딩할 때 골치아픈 것 중의 하나가 generate key(오라클의 sequence, MS SQL의 identity, MySQL의 auto_increment 등)을 다루는 것이다.

아 글쎄~ 요즘세상에 JDBC를 날로 쓰는 경우가 어딨냐고-.-;

대부분의 ORM(JPA, Hibernate, iBATIS 등)에서는 여기에 대한 별도의 처리방법이 존재하지만,
ORM까지 동원하기엔 좀 그렇고-.-, 그렇다고 JDBC를 날로 쓰기도 좀 그렇고...
이럴 땐, commons-dbutilsspring-jdbc를 사용하게 된다.

commons-dbutils를 사용하는 경우는 사실상 JDBC를 날로 쓸 때와 큰 차이가 없으니 넘어가고...

spring-jdbc을 사용하는 경우, 그 중에서도 스프링 2.5부터 추가된 SimpleJdbcInsert의 경우를 알아보면:
SimpleJdbcInsert insert = new SimpleJdbcInsert(dataSource).withTableName("contacts").usingGeneratedKeyColumns("id");
SqlParameterSource paramSource = new BeanPropertySqlParameterSource(contact);
long generatedKey = insert.executeAndReturnKey(paramSource).longValue();
contact.setId(generatedKey);

"와~~ 깔끔하게 끝나네~"라고 기뻐하려는 찰라... 이게 derby에서(만!) 안된다. ㅠ.ㅠ

좀 뒤져봤더니 버그만 올라와 있고 해결책은 안 나와 있다. 그래서... 이렇게 구질구질한 코드를 만들었다:
KeyHolder keyHolder = new GeneratedKeyHolder();
JdbcTemplate template = new JdbcTemplate(dataSource);
template.update(new PreparedStatementCreator() {
  public PreparedStatement createPreparedStatement(Connection connection)
      throws SQLException {
    PreparedStatement pstmt = connection.prepareStatement("INSERT INTO contacts(name,email,address) VALUES(?,?,?)", Statement.RETURN_GENERATED_KEYS);
    pstmt.setString(1, contact.getName());
    pstmt.setString(2, contact.getEmail());
    pstmt.setString(3, contact.getAddress());
    return pstmt;
  }
}, keyHolder);
Long generatedKey = new Long(keyHolder.getKey().longValue());
book.setId(generatedKey); 

혹시, 더 깔끔한 방법을 알고 있는 분 계시면 공유 좀 해주셈~~

Posted by iolo
hacking/java2008/10/29 18:33
크리에이티브 커먼즈 라이선스
Creative Commons License
한국 developerWorks에 기고한 번역문

원문: Use XQuery from a Java environment
번역: 자바 환경에서 XQuery 사용하기

XQuery를 처음 본게 2003년 무렵이었으니... 벌써 5년째...
작년에 W3C에 1.0 스펙이 올라왔고...
이제서야 큰 고생없이 써 볼 수 있게 됐다.

이 글에서는 설명의 편의상 XML 데이터베이스보다는 로컬 XML 파일을 대상으로 설명하고 있지만,
실제 XQuery의 유용함은 거대한 XML 노드들의 집합체, 즉 XML 데이터베이스를 대상으로 할 때 더욱 돋보인다.

튜토리얼 하나로 모든 것을 익힐 순 없겠지만, 이런 것도 있다는 맛보기로는 충분하다.

글에서는 상용 제품인 DataDirect XQuery를 사용했지만, 개인적으로는 SAXON을 추천한다.
JSR255로 등록된 XQuery API for Java 스펙을 보면 조만간 JAXQ(Java API for XQuery)가 등장할 듯...
그러면 별다른 삽질없이도 javax.xml.xquery 패키지를 통해 쓸 수 있게 되겠지... 그 동안은...

본문에도 언급했지만, XQuery를 배울려면 XPath부터 배워야 한다. XPath는 이미 자바에 기본으로 포함되어 있어서 부담없이 쓸 수 있음에도 불구하고 대부분의 개발자들은 SAX와 DOM의 숲에서 해매고 있다. 이 기회에 developerWorks의 글을 통해 XPath를 익혀보는 건 어떨까?

번역을 도와준 모토코 언뉘에게 감사를~~

Posted by iolo
hacking/web2008/10/24 17:08
크리에이티브 커먼즈 라이선스
Creative Commons License
한국 developerWorks에 기고한 번역문

원문: Develop AJAX applications like the pros, Part 3: Use DWR, Java, and the Dojo Toolkit to integrate Java and JavaScript
번역: 전문가다운 Ajax 애플리케이션 개발, Part 3: DWR, 자바, Dojo 툴킷을 사용하여 자바와 자바스크립트 통합하기

전형적인 디벨로퍼웍스 스타일의 제목... 원츄! -.-)b~

제목과는 달리 dojo 얘기는 없다.
대신, 자바 개발자들을 위한 거져 먹는 Ajax! DWR이 있다.
정말~ 쉽고! 정말~ 편하다!
장담하건데... 기존에 자바로 구축된 웹 사이트에 간단한 Ajax를 추가하는 거라면 이 보다 더 좋은 솔루션은 없다.

百問而不如一見~

Posted by iolo
hacking/java2008/08/01 01:56
크리에이티브 커먼즈 라이선스
Creative Commons License
F3에 JavaFX라는 뜬금없는 이름을 붙이곤, 자바원 2008에서 그렇게 떠들어 대더니... JavaFX의 첫번째 프리뷰 SDK가 나왔다.

포함된 것들을 보면:
1) JavaFX Compiler & Runtime tools
2) 2D Graphics and Media Libraries
3) Tutorials API docs, and Sample Code
4) NetBeans Plug-in
5) Project Nile - a suite of tools and plug-ins(포토샵/일러스트레이터용!)

그렇다... 역시 넷빈즈 플러그인만 있다. 이클립스 플러그인은... 당근 없다.
하긴... 마티스가 없는 JavaFX는 FLEX Builder없는 FLEX!

사용자 삽입 이미지

뽀대 작살!
(역시... OSX은 스샷을 위한 OS)

썰렁한 예제도 하나 올라왔는데, Java 1.6이 깔려있다면 바로 돌려볼 수 있다.
(이런 예제를 보면 쓰고 싶은 맘이 들겠냐-.-;;;)

좀 더 그럴싸한  Motorola Music을 보는게 나을려나... -.-; 아무튼 더 많은 예제는 여기에서 볼 수 있다.



Posted by iolo
TAG Java, javaFX, ria
hacking/java2008/06/05 00:10
크리에이티브 커먼즈 라이선스
Creative Commons License
한국 developerWorks에 기고한 번역문

원문: Use XStream to serialize Java objects into XML
번역: XStream으로 자바 객체를 XML로 직렬화하기

오랜만에 자바 기사 번역이다.-.-; 요즘은 완전 AJAX 전담 번역자가 된 듯...

직렬화(serialization)라고 하니까 거창해 보이지만, 정말 단순하면서도 유용한 라이브러리다. 다만, 너무 늦게 나왔다는 것이 문제라면 문제일까...

XML이 자리를 잡기 시작할 무렵, 지저분한 SAX와 메모리 귀신 DOM 사이에서 갈등하던 시절에는 apache의 commons-digester가 나름대로 유용함을 인정받았지만, 지금은 어떨까?

왠만해서 XML를 직접 파싱할 필요도 없고, 필요하다고 해도 DOM의 메모리 사용량이 별로 걱정되지 않고, 걱정된다고 하더라도 StAX같은 대안들이 넘쳐난다. 내 경우엔 스프링을 쓰다보니.. 예전처럼 여기저기 XML을 흩어놓을 일이 거의 없다.

그럼에도 불구하고 XStream은 굉장히 잘만든 깔끔한 라이브러리다. 혹시 commons-digester를 쓰고 있거나, 써야 할 일이 있다면, StAX를 모르고 배워야 겠다는 의지가 없다면... 혹은 그 마저도 귀찮다면... 그래도 JAXB는 싫다면... XStream은 "손 안대고 코 푸는" 멋진 라이브러리다.


Posted by iolo
hacking/web2008/05/13 16:47
크리에이티브 커먼즈 라이선스
Creative Commons License
자바스크립트에는 URL 인코딩과 관련해서 4가지 함수가 있다.
encodeURI(), encodeURIComponent(), escape()/unescape() 이 그것인데...
구글신께 여쭈었더니... 이렇게 다르다고 말씀해 주셨다.

정말?
일단, 실험을 해보기로 했다.

저 사이트에 나온 파일을 UTF-8EUC-KR로 각각 저장했다.

test-utf8.html, test-euckr.html
<html>
<body>
<script type="text/javascript">
var s;
s = encodeURI('http://www.google.co.kr/소 설.html');
document.write('<p>' + s + '<p>');
s = encodeURIComponent('http://www.google.co.kr/소 설.html');
document.write('<p>' + s + '<p>');
s = escape('http://www.google.co.kr/소 설.html');
document.write('<p>' + s + '<p>');
</script>
</body>
</html>

그리고 각각의 파일의 헤더 영역에 다음의 메타 태그들을 끼워넣은 파일을 두개 더 만들었다.

test-utf8-meta.html
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />

test-euckr-meta.html
<meta http-equiv="Content-Type" content="text/html;charset=EUC-KR" />

그리고, 이 페이지들을 한글 IE7, 영문 IE6, 영문 IE7, FF 2.0 으로 브라우져로 테스트 했다. 혹시나 싶어서 IE의 경우엔 항상 "UTF-8로 URL을 보내기" 옵션도 바꿔가면서 해봤는데... 말그대로 URL을 보내는 것이 아니라서 차이가 없었다.

이런 삽질을 왜 하냐 싶겠지만...
내가 기대한 것은 첫번째 경우지만... 결과를 보면... 정말... 다들 제각각이다. -.-;;;;

test-utf8-meta.html, test_euckr.html, test-euckr-meta.html, 한글 IE7, FF
test-utf8-meta.html, 영문 IE6/7(한글 언어 팩 없음)
http://www.google.co.kr/%EC%86%8C%20%EC%84%A4.html
http%3A%2F%2Fwww.google.co.kr%2F%EC%86%8C%20%EC%84%A4.html
http%3A//www.google.co.kr/%uC18C%20%uC124.html

test-utf8.html, 한글 IE7
http://www.google.co.kr/????html
http%3A%2F%2Fwww.google.co.kr%2F%3F%3F%3F%3Fhtml
http%3A//www.google.co.kr/%3F%3F%3F%3Fhtml

test-utf8.html, 영문 IE6/7(한글 언어 팩 없음)
http://www.google.co.kr/%C3%AC%E2%80%A0%C5%92%20%C3%AC%E2%80%9E%C2%A4.html
http%3A%2F%2Fwww.google.co.kr%2F%C3%AC%E2%80%A0%C5%92%20%C3%AC%E2%80%9E%C2%A4.html
http%3A//www.google.co.kr/%EC%u2020%u0152%20%EC%u201E%A4.html

test-euckr.html, 영문 IE6/7(한글 언어 팩 없음)
test-euckr-meta.html, 영문 IE6/7(한글 언어 팩 없음)
http://www.google.co.kr/%C2%BC%C3%92%20%C2%BC%C2%B3.html
http%3A%2F%2Fwww.google.co.kr%2F%C2%BC%C3%92%20%C2%BC%C2%B3.html
http%3A//www.google.co.kr/%BC%D2%20%BC%B3.html

정리해보자:
  1. meta 태그는 반드시 넣어줘야 한다. 없으면... IE가 힘들어 한다.
  2. meta 태그가 있어도 영문 환경에서 한글 언어 팩이 안깔려있으면 euc-kr은 황~이다.
  3. URL을 통째로 인코딩할 때는 encodeURI(), URL의 파라메터만 인코딩할 때는 encodeURIComponent()를 쓰면 된다.
  4. escape()/unescape()는 잊어버려라.
  5. 왠만하면 URL에 인코딩이 필요한 꺼리(한글... 공백... 이런 거)는 넣지 말자.

덧1.
여기서 의문점 한가지 더! 그렇다면 자바의 java.net.URLEncoder는 어떨까?
결론은 이녀석은 자바스크립트의 encodeURI()와 동일하다.
주의할 점은 java.net.URLEncoder의 두개의 함수 중의 파라메터가 두개인 녀석(캐릭터 인코딩을 지정해주는)을, 두번째 파라메터를 "UTF-8"로 지정해서 사용해야 한다는 것이다. 파라메터가 한 개인 첫번째 녀석을 쓰면... 플랫폼의 기본 인코딩(-Dfile.encoding)을 따라가므로 개차반(?) 난다.
자바에선 이것 저것 다 잊어버리고... 그냥 바이트 배열로 뽑아서 commons-codec의 URLCodec을 쓰는게 정신 건강에 이롭다.

덧2.
나름 좀 한다는 개발자들 조차 인코딩과 캐릭터셋에 대해서 오락가락한다. 자바 API 개발자들 조차 헷갈리고 있으니...(java 1.6의 String#getBytes()와 1.3의 String#getBytes()의 파라메터 이름을 보시라~~. commons-codec의 URLCodecgetEncoding()getDefaultCharset()도 보시라~~). 오죽하랴마는... 인코딩은 인코딩이고, 캐릭터셋은 캐릭터셋이다. 말하자면, "유니코드(캐릭터셋)에 속한 글자들은 UTF-8(인코딩)이나 UTF-16(인코딩)등으로 표현할 수 있다." 정도 일까? 그러니까, UTF-8이건 EUC-KR이건, URL 인코딩을 하는 입장에선 그냥 바이트 배열일 뿐이다. 더 어렵나?? =3=3=333

Posted by iolo
hacking/java2008/03/15 13:50
크리에이티브 커먼즈 라이선스
Creative Commons License
한국 developerWorks에 기고한 번역문

원문: The Geronimo renegade: Using integrated packages: GlassFish JSTL 1.2 and Apache Geronimo 2.0
번역: Geronimo의 배신: GlassFish JSTL 1.2와 Apache Geronimo 2.0 통합 패키지 사용하기

장황한 제목의 기고문은 제목과 무관하게... 자바 웹 기술 발전사를 다룬 글이다.

내용을 요약하면:
  1. Servlet
  2. JSP
  3. JSP + Serlvet (Model 2)
  4. JSP + JSTL
  5. JSP + JSTL + EL
  6. JSP + JSF
  7. JSP + JSF + JSTL + Unified EL
결론을 요약하면:
"Apache Genonimo도 위의 마지막 7번 조합을 지원하니 꼭 한 번 써보세요~" 되시겠다.

굳이 따로 설명할 필요도 없을 정도로 쉬운 내용이지만, 복습 차원에서 한번 읽어보면 좋을 듯...

Posted by iolo
hacking/java2008/03/15 13:49
크리에이티브 커먼즈 라이선스
Creative Commons License
한국 developerWorks에 기고한 번역문 + 보너스

원문: Monitor and diagnose performance in Java SE 6
번역: Java SE 6의 성능 모니터링 및 진단

자바 6가 2006년 12월에 나왔으니까... 벌써 2년이 넘었다.
그런데, 주변을 보면 Java 6의 새로운 기능들을 활용하는 경우를 거의 보지 못했다.

오히려 프로젝트에 Java 6을 쓰겠다고 하면 안정성이 검증되지 않은 플랫폼을 선택하는 것은 너무 위험하다는 걱정아닌 걱정을 듣기도 했다. 흠... 이 얘기는 나중에 따로 하고 -,.-;

자바 6에서 언어적인 측면을 빼고 가장 크게 달라진 부분이 JConsole이다.
JConsole은 한마디로 요약하면 스윙으로 만든 JMX 클라이언트 어플리케이션이다.
생긴 건 구리지만(썬이 만든게 다 그렇지 않나... -.-) 쓸모로 따지면 쵝오! -.-)b

지금이라도 JConsole을 활용해보자. 어플리케이션이 자바 6 위에서 돌고 있다면 따로 해줄 것도 없다. 그냥 JConsole을 실행시켜서 원하는 자바 어플리케이션과 연결하면 그만이다.(Attach API 참조)

기회가 되면 jsadebugd(번역할 때 애 먹었다... Serviceablility Agent Debug Daemon이라니...)에 대해서 좀 더 써 볼까 한다...


Posted by iolo
hacking/java2008/02/19 12:23
크리에이티브 커먼즈 라이선스
Creative Commons License
새로운 이클립스용 Maven2 플러그인 Q.. 줄여서 q4e가 등장했다.(고 하기엔 좀 오래된 얘기일지도...)

현재로썬(0.4) WTP 지원이 원할하지 않아서 M2WTPlibcopy같은 플러그인과 같이 써야한다.(m2eclipse도 예전에는 비슷한 삽질이 필요했는데 최근 버전은 WTP와 잘 붙는다.) 대신 mavenide(넷빈즈용 maven 플러그인)에 있던 의존성 그래프같은 기능을 갖고 있다.

이클립스 공식 프로젝트로 제안됐는데... 글쎄...
http://www.eclipse.org/proposals/iam/

나름대로 이유가 있긴하지만, m2eclipse가 어느 정도 자리를 잡아가는 시점에서 이렇게 fork하는 모양새가 그닥 좋아보이진 않는다.

예전에 써두었다가 포스팅 안했던 건데, 포스팅할거리도 없고... -.-;;;
Posted by iolo
hacking/java2008/02/14 10:34
크리에이티브 커먼즈 라이선스
Creative Commons License
JCO라고 불리우는 정체 불명의 단체가 주관하는 아홉번째 자바 개발자 컨퍼런스~

순선옹의 이적 후 첫 공식 데뷔 무대가 재밌을 꺼 같네~ 우후훗~

시간 내용
10:30
~
11:30
접수 및 입장
11:30
~
11:40
개회사
11:40
~
12:10
기조연설#1
기조연설 #2
12:10
~
12:30
2007 대한민국 소프트웨어 공모대전 (제7회 JCO 자바 소프트웨어 공모전) 시상식
12:30
~
12:40
쉬는 시간 및 트랙 준비, 이동 시간
트랙 주제 Java Practice java Technology Enterprise
Computing
Software Engineering Data Management
& Business
사회자 김소리 김홍회 최진호 전영민 김형배
12:40
~
13:20
New Java Grammar
- Java5, Java6
양수열
(자바챔피언)
자바 기반 대용량
접속 처리 노하우
- Daum 아고라
(가이아) 사례
백명석 (DAUM )
Open Document
기술전략과 IBM의 역할
Michael Karasick
(IBM / Director of Lotus Software Development)
아키텍트로 가는 길
백용규
(동부 CNI / 과장)
Oracle Coherence
: In-memory Data Grid 솔루션
김태완
(오라클 / 차장)
13:20
~
13:30
쉬는 시간 및 트랙 준비, 이동 시간
13:30
~
14:10
Eclipse Overview 윤성준 (이니시스) 오픈 소스
프레임워크를
활용한 비즈니스
어플리케이션
개발 방안
김창제
(삼성SDS / 팀장)
차세대 프로그래밍
플랫폼으로써의
미들웨어
김종규
(TmaxSoft
/ 수석연구원)
레거시 코드
관리 전략
허광남
(GS이숍 / 과장)
효율적인 데이터
관리를 위한
Hybrid DBMS
서정훈
(알티베이스 / 책임)
14:10
~
14:20
쉬는 시간 및 트랙 준비, 이동 시간
14:20
~
15:00
이클립스 SWT
실용주의
박용우
(JCO / 고문)
Ajax와 Java 바인딩 김영보
(AJAX Prototype
완전정복 저자
/ 프리랜서)
APM,리소스 중심적
애플리케이션 성능
모니터링
김성조
(제니퍼소프트
/ 이사)
S/W 품질 요소와 ATAM
김훈섭
(SK C&C / 차장)
Google Infra Cloning
김형준
(jaso.co.kr / 시삽)
15:00
~
15:10
쉬는 시간 및 트랙 준비, 이동 시간
15:10
~
15:50
스티브 맥코넬
이야기
박재호
(Rapid Development 역자)
Functional Programming for Java Programmers
송치형
(이노무브
/ 수석위원)
누구도 들려주지
않는 Service
이야기
(SaaS로 가는 길)
손영수
(데브피아 아키텍쳐 포럼
/ 시삽)
패턴 언어
(Pattern Language)
산책
최상훈
(JCO / 부회장)
글로벌/한국 인터넷 비즈니스 현황과 SW개발자를 위한 창업 프로세스
류한석
(소프트뱅크미디어랩 / 소장)
15:50
~
16:00
쉬는 시간 및 트랙 준비, 이동 시간
16:00
~
16:40
Over the Struts
- Struts2
현철주
(아첸소프트웨어
/ 대표)
UCity
서비스 구축과
연동 통합을
위한 기술
강신동
(UJAVA.ORG
/ 시삽)
The Large Programming Model - BPM
장진영
(UEngine.org
/ PM)
애자일에 대한
7가지 교훈
김창준
(애자일 컨설팅
/ 대표)
경력관리,취업을
위한 조언
오규덕
(인크루트 / 차장)
16:40
~
16:50
쉬는 시간 및 트랙 준비, 이동 시간
16:50
~
17:30
네이버
OPEN API와
오픈소스
권순선
(NHN)
Spring OSGi
이일민
(epril.com / 대표)
JavaEE,
GlassFish의 진화
조인영
(SUN / 자바에반젤리스트)
실용주의(Pragmatic)
개발 환경 -2008년 개발자의 하루
박재성
(javajigi.net
/ 시삽)
오픈소스를 통한
비지니스 모델
송승호
( 레드 햇
/ 컨설턴트)
17:30
~
17:40
쉬는 시간 및 폐회 준비 시간
17:40
~
18:00
경품 추첨 및 이벤트, 폐회사
* 자바인의 밤
Posted by iolo
hacking/java2008/01/29 16:26
크리에이티브 커먼즈 라이선스
Creative Commons License
기사: 중급 자바 개발자의 난관, 클래스 로딩 문제 분석하기

얼마 전에 한국 developerWorks에서 기획 기사 요약문을 써달라고 해서 기고한 글이다.

내 이름이 들어가서가 아니고(어차피 내가 쓴 것도 아니지만), 꽤 볼만한 글이다.

필자의 회사에서 만든 제품도 커스텀 클래스로더를 써서 현란한 짓거리(?!)를 좀 하는데... 대다수의 사람들이 그 코드를 이해하지 못하고 있어서 안타까웠던 기억이 있다.

요즘 자바 웹 개발자들이라면 톰캣을 많이 쓸텐데... 톰캣의 클래스로딩 정책을 정확하게 이해하지 못한 탓에  $CATALINA_HOME/server/lib에 넣어야할  라이브러리, $CATALINA_HOME/shared/lib에 넣어야할 라이브러리,  $CATALINA_HOME/common/lib에 넣어야할  라이브러리를 구분하지 못하는 경우를 많이 보아왔다. $JAVA_HOME/lib/ext 에 넣어야하는 경우와 java.endorsed.dirs 시스템 프로퍼티로 지정해야하는 경우를 구분하지 못하는 경우도 꽤 많다. 사실, 클래스로더의 기본 원리만 이해하면 당연한 것인데, case-by-case로 외워서 처리하다보니... 알고 있는 'case'가 아니면 try-and-error로 해결하게 된다.

아무튼 똑같은 얘기 되풀이해봐야 재미없으니, (스스로를 자바 중급 개발자라고 생각한다면) 그냥 위의 링크를 눌러서 한번 쭈욱 둘러보시길~

덧. 같이 기고한 자바 애플리케이션 시작하기: 개인용 영화 데이터베이스 애플리케이션 개발은... 제목이 틀렸다. 자바가 아니고 PHP다. 기고하면서 developerWorks의 원문이 틀렸음을 지적했는데... 무슨 정책이 있는 건지.. 틀린 채로 그냥 올라갔다. 뭐... 크게 볼만한 기사는 아니니까...-.-;;;;

Posted by iolo
hacking/java2007/12/11 14:08
크리에이티브 커먼즈 라이선스
Creative Commons License
엄밀하게 말하면 eclipse용 maven플러그인의 문제라기보다는 maven-embedder의 문제인데...

몇 가지 해결책이 있다.

1. m2eclipse의 홈페이지 FAQ에 나오는 방법...

pom.xml에 다음의 내용을 추가해 준다:
<dependency>
   <groupId>com.sun</groupId>
   <artifactId>tools</artifactId>
   <version>1.5.0</version>
   <scope>system</scope>
   <systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>

이 방법이 제일 간단한 방법이지만, jdk를 기본 경로(예: c:\Program Files\Java\jdk1.5.0_13)에 설치하지 않았다면 제대로 동작하지 않는다. 내 경우가 바로 그런 경우인데(예: d:\devel\jdk1.5.0_13), 다행이도 JAVA_HOME 환경 변수가 저 디렉토리를 가리키고 있어서 다음과 같이 수정했다:
   <systemPath>${env.JAVA_HOME}/lib/tools.jar</systemPath>

2. tools.jar를 수동으로 로컬 저장소에 추가하는 방법...

혼자하는 프로젝트에서 유용한 방법이다. 콘솔을 열고 다음 명령을 실행한다:
mvn install:install-file -Dfile=D:\devel\jdk1.5.0_13\lib\tools.jar -DgroupId=com.sun -DartifactId=tools -Dpackaging=jar -Dversion=1.5.0

여기서 tools.jar의 완전한 경로는 원하는대로 바꿔주면 된다.

3. tools.jar를 수동으로 원격 저장소에 추가하는 방법...

여러 사람이 진행하는 프로젝트에서 유용한 방법인데... 조금 복잡하다. 이 방법을 사용하기 위해서는 쓰기(업로드)가능한 원격 저장소가 미리 준비되어 있어야 한다. 일단 원격 저장소가 준비되어있다면,  콘솔을 열고 다음 명령을 실행한다:
mvn deploy:deploy-file -Dfile=D:\devel\jdk1.5.0_13\lib\tools.jar -Durl=dav:http://url.to.remote.repository -DrepositoryId=remote-repository -DgroupId=com.sun -DartifactId=tools -Dpackaging=jar -Dversion=1.5.0

여기서 tools.jar의 완전한 경로는 원하는대로 바꿔주면 된다. 또한 원격 저장소의 완전한 url과 저장소 id(settings.xml에 정의된 server 항목)도 적절하게 바꿔주어야 한다.

대부분의 경우 scp를 쓰거나 archiva의 webdav을 쓸텐데... 이 때는 원격 저장소 설정을 settings.xml에 적어두는 것 외에 한가지 더 해야할 일이 있다. deploy-file goal이 사용할 wagon 라이브러리들을 maven의 lib디렉토리(예: d:\devel\apache-maven-2.0.8\lib)에 넣어두는 것이다. webdav을 쓰는 경우에는 다음의 파일(괄호 안은 groupId, 버전은 다를 수 있음)들이 필요하다:
wagon-webdav-1.0-beta-2.jar (org.apache.maven.wagon)
webdav-0.4.jar
(it.cloud)
slide-webdavlib-2.1.jar  (slide)
commons-httpclient-2.0.2.jar (commons-httpclient)
commons-logging-1.0.4.jar (commons-logging)
plexus-utils-1.4.7.jar (org.codehaus.plexus)

내 경우엔 여러 사람이 프로젝트에 참여하기 때문에 세번째 방법을 써서 1.5.0와 1.6.0버전의 tools.jar를 각각 등록해 두었다.

Posted by iolo
hacking/java2007/12/08 16:46
크리에이티브 커먼즈 라이선스
Creative Commons License
기존 프로젝트를 maven으로 마이그레이션할 때 디렉토리 구조를 어떻게 할 것인가 하는 문제때문에 늘 고민하게 된다. 결론부터 말하면, 두가지 방법이 있다.

1. 기존 디렉토리 구조를 그대로 두고, maven을 적절하게 설정한다.
2. 기존 디렉토리 구조를 maven의 표준(권장) 디렉토리 구조로 변경한다.

후자의 경우가 확실하긴 하지만, cvs를 쓰고 있다면 대략 낭패(?!)다. svn을 쓴다면 그나마 다행이지만... 여러 사람이 함께 작업하는 프로젝트라면 조금 귀찮은 문제들이 있다.

내가 기존에 사용하던 프로젝트의 디렉토리 구조는 (대충) 다음과 같다:

  • src
    • java : *.java
    • res : *.properties 등의 리소스들...
    • test: *Test.java 와 리소스들...
  • build
    • classes : 출력 파일들
  • WebContent : 웹 리소스들((Eclipse/WTP를 사용할 경우에만 필요하다)

전형적인 ant용 디렉토리 구조인데, 이 구조를 손대지 않고 maven으로 빌드를 하기 위해서 pom.xml에 다음과 같은 내용을 추가했다:

    <build>
        <directory>${basedir}/build</directory>
        <sourceDirectory>${basedir}/src/java</sourceDirectory>
        <outputDirectory>${basedir}/build/classes</outputDirectory>
        <testSourceDirectory>${basedir}/src/test</testSourceDirectory>
        <testOutputDirectory>${basedir}/build/test-classes</testOutputDirectory>
        <resources>
            <resource>
                <directory>${basedir}/src/res</directory>
            </resource>
        </resources>
        <testResources>
            <testResource>
                <directory>${basedir}/src/test</directory>
                <excludes>
                    <exclude>*.java</exclude>
                </excludes>
            </testResource>
        </testResources>
        <plugins>
            <plugin>
                <artifactId>maven-war-plugin</artifactId>
                <configuration>
                    <warSourceDirectory>${basedir}/WebContent</warSourceDirectory>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <reporting>
        <outputDirectory>${basedir}/build/site</outputDirectory>
    </reporting>


약간 골치아팠던 것이, 내 경우엔 test용 클래스와 리소스들을 하나의 디렉토리(src/test)에 몰아넣었는데, maven은 따로 구분한다(src/test/java와 src/test/resources)는 점이다. 그래서 testSourceDirectory와 testResource 둘 모두에 같은 디렉토리를 설정하고 testResource에 *.java를 exclude하도록 설정했다.

대충 돌아가는것 같은데, 뭔가 빠트린게 있을까.. 살짝 불안^^;

Posted by iolo
TAG Java, maven
hacking/java2007/12/04 01:11
크리에이티브 커먼즈 라이선스
Creative Commons License
최근에는 본의 아니게 AJAX로 먹고 살고 있지만, 내 밥줄은 기본적으로 자바다. 그리고, 내가 자바로 코딩할 때 가장 많이 사용하는 라이브러리(프레임웍을 포함해서) 중의 하나가 spring이다. 즐겨쓰던 IoC 컨테이너였던 avalon 프로젝트가 뽀개지면서 대안으로 spring 1.2.x를 처음 쓰기 시작했는데, 벌써(이제서야?) 2.5 버전이 나왔다.

프레임웍 라이브러리의 특성상(하위호환성이 무척 중요하다!) 큰 변화가 있기 힘들지만, 2.5에서는 호환성을 깨지 않으면서 많은 눈에 띄는 변화가 있었다. 이 글에서는 그 중에서 annotation 지원에 대해서 알아보겠다.

스테레오타입 어노테이션

클래스에 붙여서 해당 클래스가 컴포넌트 스캐닝의 대상이고, 스프링에 의해서 관리될 것임을 표시한다. 즉, <beans> XML 설정 파일에서 <bean>으로 선언한 것과 같은 효과를 낸다.

@Component
메타 어노테이션. 다른 모든 스프링 스테레오타입 어노테이션 및 커스텀 Qualifer 어노테이션의 부모 어노테이션.

@Service
상태없는 서비스 컴포넌트.

@Repository

저장소 컴포넌트(DAO 등).

@Aspect
@AspectJ의 어스펙트.

@Controller
Spring MVC 컨트롤러.

스테레오타입은 스테레오타입일 뿐!! 너무 심각한 의미를 부여하지 말자! 대부분의 경우엔 @Service으로 충분하다. @Controller에 대해서는 다음 기회에 좀 더 자세히 알아보기로 하고...

위의 어노테이션이 붙은 클래스를 찾기 위해서 모든 클래스 패스를 뒤지는 것은 곤란하므로.. 아래와 같은 방식으로 스캔할 범위를 지정한다:

예) 가장 단순한 사용 예: 특정 패키지 이하의 모든 클래스에 대해서 스테레오타입 어노테이션이 붙은 클래스를 찾아서 스프링 관리 대상에 포함 시킴.(빈 선언)

<beans>
  <context:component-scan base-package="com.mycompany.myblog" />
   ...
</beans>


의존성 주입(DI; Dependency Injection) 어노테이션

@Autowired
생성자, 메소드, 필드에 붙여서 스프링을 통해 인젝션될 것임을 표시한다.

@Qualifier
@Autowired이 붙은 필드 또는 메소드의 인자에 붙여서 인젝션할 빈을 검색하기 위한 더 정확한 조건을 지정한다.


예) 필드에 지정
@Autowired
@Qualifier("myDataSource“)
private DataSource orderDataSource


예) 메소드에 지정
@Autowired
public void createTemplates(DataSource ds, ConnectionFactory cf) {
   this.jdbcTemplate = new JdbcTemplate(ds);
   this.jmsTemplate = new JmsTemplate(cf);
}


예) @Qualifer와 함께 지정
public class JdbcOrderRepositoryImpl implements OrderRepository {
   @Autowired
   public void init(
      @Qualifier("myDataSource“) DataSource orderDataSource,
      @Qualifier("otherDataSource") DataSource inventoryDataSource,
      MyHelper autowiredByType) {
         // ...
  }
  ...
}


JSR-250 어노테이션

JSR-250은 BEA WebLogic에서 제공되던 것을 JSR을 통해 표준화한 것인데, @Resource어노테이션은 JNDI 리소스 인젝션을 위해 꽤 많이 쓰이고 있는 것 같다.

@Resource
JSR-250에서는 JNDI 리소스만 인젝션할 수 있었지만, 스프링 2.5에서는 스프링을 통해 관리되는 모든 빈을 인젝션할 수 있다.

@PostConstruct
2.0에서는 InitializingBean 인터페이스를 구현하고 afterPropertiesSet()에서 수행하거나, bean설정에서 init-method 속성으로 지정했다.

@PreDestory
2.0에서는 DisposableBean 인터페이스를 구현하고 destroy()를 정의하거나, bean설정에서 destroy-method 속성으로 지정했다.

개인적으로 스프링 전용인 @Autowired보다는 @Resource를 선호하는 편인데, @Qualifer를 쓸 수 없다는 단점이 있지만, @Resource(name="dataSource")처럼 빈 이름을 지정할 수 있으므로 대부분의 경우엔 충분하다.

백문불여일견, 백견불여일타, 백타불여일런!

예) 스프링 2.0.x (스프링에 대한 컴파일 타임 의존성이 없음)
public class JdbcBlogdao implement BlogDao {
   private DataSource dataSource;
   public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; }
   public void init() throws Exception { ... }
   public void destroy() throws Exception { ... }
   ...
}

<beans>
   <bean id="blogDao" class="mypackage.JdbcBlogDao" init-method="init" destroy-method="destroy">
      <property name="dataSource" ref="dataSource />
      ...
   </bean>
   ...
</beans>

예) 스프링 2.0.x(스프링에 대한 컴파일 타임 의존성을 가짐)
public class JdbcBlogdao implement BlogDao, InitializingBean, DisposableBean {
   private DataSource dataSource;
   public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; }
   public void afterPropertiesSet() throws Exception { ... }
   public void destroy() throws Exception { ... }
   ...
}

<beans>
   <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">...</bean>
   <bean id="blogDao" class="mypackage.JdbcBlogDao">
      <property name="dataSource" ref="dataSource />
      ...
   </bean>
   ...
</beans>

예) 스프링 2.5(어노테이션과 컴포넌트 스캔을 사용)
@Repository("blogDao")
public class JdbcBlogDao implements BlogDao {
   @Resource
   private DataSource dataSource;
   @PreConstruct
   public void init() throws Exception { ... }
   @PostDestroy
   public void destroy() throws Exception { ... }
   ...
}

<beans>
   <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">...</bean>
   <context:component-scan base-package="com.mycompany.myblog" />
   ...
</beans>


다음에는 "Spring MVC 어노테이션"에 대해서 알아볼 생각인데...
틈나는대로 적겠지만, 그 전에 2.6이 나올지도... -.-;

Posted by iolo
hacking/java2007/10/12 12:06
크리에이티브 커먼즈 라이선스
Creative Commons License
썬의 홈페이지에 실린 인터뷰 기사를 보다가...

Java의 오랜 미신 중에 하나...
"String 더하기 보다 StringBuffer append가 빠르다!?"

예를 들어... 아래의 코드는:

public static String concat1(String s1, String s2, String s3,
        String s4, String s5, String s6) {
    String result = "";
    result += s1;
    result += s2;
    result += s3;
    result += s4;
    result += s5;
    result += s6;
    return result;
}

이렇게 짜는게 좋다고... 가르치고 배운다. 나도 그렇게 배웠다:

public static String concat2(String s1, String s2,
        String s3, String s4, String s5, String s6) {
    StringBuffer result = new StringBuffer();
    result.append(s1);
    result.append(s2);
    result.append(s3);
    result.append(s4);
    result.append(s5);
    result.append(s6);
    return result.toString();
}

결론을 먼저 얘기하면, 새빨간 거짓말이다. 적어도 지금은 그렇다. 1.5 버전 이후의 썬의 자바 컴파일러를 사용한다면 확실히 그렇다.

StringBuffer를 사용해서 효과를 볼려면 이 정도는 해 줘야 한다:

public static String concat3(String s1, String s2, String s3,
        String s4, String s5, String s6) {
    return new StringBuffer(
        s1.length() + s2.length() + s3.length() + s4.length() +
        s5.length() + s6.length()).append(s1).append(s2).
        append(s3).append(s4).append(s5).append(s6).toString();
}

버퍼를 최초에 한번만 할당하면 append할때마다 버퍼 재할당을 하지 않으므로 확실히 빨라진다.
부작용은 코드가 극단적으로 읽기 힘들어 진다는 점. -.-;

옛날 얘기는 이쯤하고, 요즘 얘기를 해보자.

Java5에서 StringBuilder라는 새로운 클래스가 소개되었는데... 한마디로 요약하면 쓰레드에 안전하지 않은 StringBuffer다. 그런데 String은 immutable이라서 동기화 문제가 거의 없으므로, 예전에 StringBuffer쓰던 자리에 StringBuilder를 쓰면 된다.

똑같은 기능을 하는 함수를 가장 간단하게 구현하면 이렇다:

public static String concat4(String s1, String s2, String s3,
    String s4, String s5, String s6) {
    return s1 + s2 + s3 + s4 + s5 + s6;
}

1.5버전 이후의 썬의 자바 컴파일러는 concat4()처럼 짜면 StringBuilder append를 사용한 코드를 생성한다.

(위의 concat3()에서 사용한 방법까지 적용하면) 가장 효율적으로 구현하면 이렇게 된다:

public static String concat5(String s1, String s2, String s3,
        String s4, String s5, String s6) {
    return new StringBuilder(
        s1.length() + s2.length() + s3.length() + s4.length() +
        s5.length() + s6.length()).append(s1).append(s2).
        append(s3).append(s4).append(s5).append(s6).toString();
}

그러나, 여기서 고려해야할 점 두 가지:
1. 지금은 가장 효율적인 concat5()가 Java7이나 그 이후에도 가장 효율적이라는 보장이 없다.
2. concat4()가 concat5()보다 훨씬 읽기 좋다.

public static String concat6(String s1, String s2, String s3,
        String s4, String s5, String s6) {
    return new StringBuilder(BUFFER_SIZE).append(s1).append(s2).
        append(s3).append(s4).append(s5).append(s6).toString();
}


결론은:
1. 특별한 이유가 없다면 성능도 좋고 읽기도 좋은 concat4()가 최선의 선택이다.
2. 그러나 추가적인 계산없이, 버퍼 크기를 미리 알 수 있다면 concat6()도 나쁘지 않다.
3. 역시... 짜는 넘 맘이다.


Posted by iolo
hacking2007/10/01 19:32
크리에이티브 커먼즈 라이선스
Creative Commons License
자바로 처음 개발하는 사람들은 .properties파일의 인코딩 때문에 헤맨 경험이 있을 것이다.

native2ascii같은 프로그램을 사용해서 변환을 해줘야하는데... 그게 무척 번거롭기 때문이다.

이클립스를 주로 사용한다면 몇가지 선택이 있다. kenu님이 소개하신 propedit 플러그인 은 일괄적으로 한 언어를 주욱 편집할 때 편하고, 아래에 소개하는  ResourceBundleEditor 플러그인은 여러 개의 언어를 비교하면서 편집(교정/리팩토링)할 때 편하다.
사용자 삽입 이미지
개인적으로는 점으로 분리한 항목들을 계층 구조로 보여주는 기능때문에 ResourceBundleEditor를 선호하는 편이다. 또한, 모든 언어의 번역이 채워지지 않은 항목을 (위의 그림처럼) 노란색 삼각형 아이콘으로 표시해주는 기능도 무척 유용하다.
다만 이클립스 업데이트 사이트를 제공하지 않아서, 다운로드 받은다음 수동으로 설치해야 한다는 것이 조금 귀찮~.~ 자세한 내용은 http://www.resourcebundleeditor.com/ 가보시면 아시겠지만.. Donate 링크가 있다.

ant를 사용한다면 native2ascii task를 사용하면 된다. 여기서 중요한 것이 이 태스크가 (JRE에는 없고)JDK에 포함된 tools.jar를 필요로 한다는 점이다. 왜? 필요한지 나한테 묻지마라.

netbeans를 주로 사용한다면, netbeans용 native2ascii플러그인을 쓰면 된다. 써보면 알겠지만 열라 구리다. -.-;;; 뭔가 더 좋은게 있을꺼 같은데...

(아마 없겠지만) maven을 사용한다면 maven2용 native2ascii 플러그인을 쓸 수 있겠지만... 요즘도 잘 동작할지 장담은 못하겠다. -.-;;;;

사실... 더 구린건... 애초에 이런 툴이 필요하다는 사실이다.
그냥 utf-8 또는 legacy로 인코딩된 파일들을 Properties.load()가 잘 읽어들이면 되는 일 아닌가?

Posted by iolo
hacking/java2007/01/28 16:54
크리에이티브 커먼즈 라이선스
Creative Commons License
싱글톤 패턴의 전형적인 자바 구현:
  1. public class Singleton {
  2.   static Singleton instance;
  3.   public static synchronized Singleton getInstance() {
  4.     if (instance == null) {
  5.       instance == new Singleton();
  6.     }
  7.     return instance;
  8.   }
  9. }
위의 구현의 문제점은 getInstancesynchronized는 것이다.

그래서 좀 지저분하지만 현실적인 해결책으로:
  1.   public static Singleton getInstance() {
  2.     if (instance == null) {
  3.         synchronized (Singleton.class) {
  4.            if (instance == null) {
  5.               instance == new Singleton();
  6.            }
  7.         }
  8.     }
  9.     return instance;
  10.   }
이런 식의 코드를 쓰곤 했는데...

여기~ 더 멋진 방법이 있다!
  1. public class Singleton {
  2.   static class SingletonHolder {
  3.     static Singleton instance = new Singleton();
  4.   }
  5.   public static Singleton getInstance() {
  6.     return SingletonHolder.instance;
  7.   }
  8. }

스프링까지 동원하기 뭣한 작은 프로그램이나, 프레임워크와 독립적으로 동작해야하는 유틸리티 클래스에서 유용하게 써먹을 수 있겠다.

'hacking > java' 카테고리의 다른 글

Maven2와 Eclipse/WTP 함께쓰기 (2)  (0) 2007/09/13
Maven2와 Eclipse/WTP 함께쓰기  (0) 2007/09/11
singleton과 lazy loading...  (0) 2007/01/28
Java6 XMLOutputFactory 유감  (2) 2007/01/15
XML Exodus...  (3) 2007/01/07
아니~ 버~ㄹ써! Java6~  (0) 2006/12/12
Posted by iolo
hacking/java2007/01/15 22:36
크리에이티브 커먼즈 라이선스
Creative Commons License
오늘 삽질하다가... 발견한 Sun의 Java6의 javax.xml.stream.?XMLOutputFactory 소스의 일부... -.-;;;;;

  1. public abstract class XMLOutputFactory {
  2. ...
  3. /**
  4. * Create a new instance of the factory using the default factory location
  5. * mechanism (check env. variable, jaxp.properties, jar services manifest,
  6. * in this order)
  7. *
  8. * @throws FactoryConfigurationError if an instance of this factory cannot be loaded
  9. */
  10. public static XMLOutputFactory newInstance() throws FactoryConfigurationError {
  11.     return (XMLOutputFactory) FactoryFinder.find("javax.xml.stream.XMLOutputFactory",
  12. "com.sun.xml.internal.stream.XMLOutputFactoryImpl");
  13. }
  14.  
  15. /**
  16. * Create a new instance of the factory
  17. *
  18. * @param factoryId Name of the factory to find; not the class name but the
  19. *    property name to use
  20. * @param classLoader classLoader to use
  21. * @return the factory implementation
  22. * @throws FactoryConfigurationError if an instance of this factory cannot be loaded
  23. */
  24. public static XMLInputFactory newInstance(String factoryId, ClassLoader classLoader)
  25. throws FactoryConfigurationError {
  26.     return (XMLInputFactory) FactoryFinder.find(factoryId, "com.sun.xml.stream.XMLOutputFactoryImpl", classLoader);
  27. }
  28. ...

뭐가 이상하냐고?

첫번째 함수와 두번째 함수의 리턴타입...

?XMLOutputFactory가 왜! ?XMLInputFactory를 create하는 것이냐!(버럭!!)

해결책: 그냥 [http]우드스탁을 쓰던가... [http]BEA의 StAX 참조구현을 쓰면 된다.

'hacking > java' 카테고리의 다른 글

Maven2와 Eclipse/WTP 함께쓰기  (0) 2007/09/11
singleton과 lazy loading...  (0) 2007/01/28
Java6 XMLOutputFactory 유감  (2) 2007/01/15
XML Exodus...  (3) 2007/01/07
아니~ 버~ㄹ써! Java6~  (0) 2006/12/12
Java, finally GPLed  (0) 2006/11/14
Posted by iolo
TAG Bug, Java, stax
hacking/java2007/01/07 22:17
크리에이티브 커먼즈 라이선스
Creative Commons License
거의 한 달동안 정체 불명의 스펙들 속에서 허우적 거리고 있다.

DOM과 SAX로 모든걸 해결하던 배고픈 시절은 갔다고 굳게 믿었다. 넘쳐나는 스펙들을 보며 만세를 불렀다. 그리고, 그 스펙들의 공수표에 좌절하고 있다.

한달 동안 뒤적거린 XML 관련 스펙들을 나열해보자:
  • DOM:굳이 설명이 필요없을 듯.
  • SAX:상동
  • XSLT:상동
  • XPATH: 1.0 스펙까진 어느 정도 알고 있었다. 2.0은 그야말로.. 경천동지~ 상전벽해~ 말로만 하는거면 뭘 못하냐고-.-.
  • ?XQuery:궁극의 해결책이라고 믿었다. 천만의 말씀 만만의 콩떡이더라.
  • ?XUpdate:처음 봤을땐 이건 어디서 굴러먹던 개뼈다귀냐라고 생각했었지만... 정말 개뼈다귀다. -.-;
  • ?XmlDb (XAPI): 정말 개뼈다귀다. -.-;;
  • ?XQueryUpdateFacility:궁국의 해결책일까? 공수표좀 그만 뿌려라! -.-;;;
  • ?StAX:자바스러운 SAX?
  • ?TrAX:자바스러운 XSLT?
  • 외 다수...

이 스펙들을 따라 뒤적거리고 설치하고, 돌려보고, 삽질도 해보고, 삭제한 녀석들을 나열해보자:
  • Xindics:그렇다. 마데인아파체다. 그것만 믿고 깔았다. 앞으로의 여정이 만만치 않을 것임을 깨달았다.
  • eXist:구세주인가? 천만의 말씀 만만의 콩떡. 앞으로 여정은 더욱 험난할 지어다.
  • ?BerkerleyDbXml:오! 오라클! 개뿔...
  • Saxon:일단 피해가자...라고 생각했으나.. 그 마저도 쉽지 않은...
  • 외 다수...

그리고, 먼 길을 돌아... 다시 DOM, SAX로 갈 수는 없어서... ?StAX와 ?TrAX로 돌아왔지만... 이 길도 그리 순탄해 보이지는 않는다.

내가 하고 싶은건..
  1. 크기가 가변적이고(수십킬로에서 수메가정도?),
  2. 일회성의(한번 처리한 파일들을 다시 처리할 일은 가물에 콩나듯?)
  3. XML 파일들을
  4. 자바로
  5. 서버사이드에서
  6. 읽고,
  7. 고치고,
  8. 저장하는
것이다.

말하자면, File-based(Disk-based) DOM 같은 거다.

eXist류의 ?XmlDb들이 거의 모든 요구사항을 만족하지만.. 한가지... (2) 일회성에서 태클을 건다. 즉, ?XmlDb로 import하고 export하는 비용이 너무 비싸다. 그냥 DOM과 SAX로 처리하는게 훨씬 싸게 먹힌다.

뱀꼬리#1 혹시 이 블로그를 보시는 분 중에서~ 어렴풋한 해결책을 제시해 주시는 분께는 맛난 커피!!!를 대접하겠다.

뱀꼬리#2 명쾌한 해결책을 제시해 주시는 분께는 맛난 밥!!!을 대접하겠다.

'hacking > java' 카테고리의 다른 글

singleton과 lazy loading...  (0) 2007/01/28
Java6 XMLOutputFactory 유감  (2) 2007/01/15
XML Exodus...  (3) 2007/01/07
아니~ 버~ㄹ써! Java6~  (0) 2006/12/12
Java, finally GPLed  (0) 2006/11/14
Java Browser Edition?  (0) 2006/09/08
Posted by iolo
TAG Java, xml
hacking/java2006/12/12 17:41
크리에이티브 커먼즈 라이선스
Creative Commons License
기뻐할 일인가, 슬퍼할 일인가...

회사의 누구 말마따나 아직 Java5 공부도 다 못했는데... ㅠ.ㅠ

뭐가 달라졌나... 한 번 구경이나 해보세~

  • 웹서비스: 웹서비스 클라이언트 제작에 필요한 API.
  • 스크립팅: 다양한 스크립트 언어 지원을 위한 프레임웍 + Rhino 자바스크립트 런타임.
  • 데이터베이스: JDBC 4.0, SQLXML 그리고 ?JavaDB(derby)!
  • 향상된 스윙: ?SwingWorker, 향상된 ?JTable 소팅/필터링, ?GroupLayout. 좀 더 빨라지고 예뻐진(?) 스윙. Vista에서 제대로 돌아감.
  • 개선된 JMX와 ?JConsole 그리고 ?DTrace 연동!
  • 컴파일러 API? javac 컴파일러를 프로그램을 통해 제어할 수 있다. 이제와서 33스럽게.. 그냥 ecj쓸란다. 그게 더 빠르고 편하더라.
  • 플러거블 어노테이션? 이건 뭘까? 아직 어노테이션도 제대로 못써먹고 있는데... 연구 대상 ;)
  • PKI, GSS, Kerberos, LDAP 통합. 보안쪽에도 뭔가 많이 추가되긴 했는데... -.-;
  • double과 스윙을 포함한 여러가지 성능 향상.

나같은 하급 개발자 입장에서 제일 눈에 띄는건 스크립팅 지원이다. 사실 Groovy때문에 JSR에 올라갔는데... 재주는 곰이 부리고 돈은 때놈이 번다더니.. Groovy는 곰이고 Rhino는 때놈인가?

스윙이 향상되었다곤 하지만.. 글쎄... 스윙으로 된 어플리케이션 구경하는게 쉬운일이 아니라서...

JDBC 4.0도 신경은 좀 쓰이지만... JDBC 3.0 스펙도 제대로 활용 못하는 처지라... Derby가 기본 포함된다는 건 꽤나 반가운 소식~

다음 버전 부터는 ?OpenJDK인데... 과연... 스윙과 AWT는 Motif의 그늘에서 벗어날 수 있을 것인가!

아무튼... Java5때 보다는 신경쓸 거리가 많지 않아서 다행(?) :p

'hacking > java' 카테고리의 다른 글

Java6 XMLOutputFactory 유감  (2) 2007/01/15
XML Exodus...  (3) 2007/01/07
아니~ 버~ㄹ써! Java6~  (0) 2006/12/12
Java, finally GPLed  (0) 2006/11/14
Java Browser Edition?  (0) 2006/09/08
mustang beta released  (0) 2006/02/16
Posted by iolo
TAG Java, java6
hacking/java2006/11/14 12:15
크리에이티브 커먼즈 라이선스
Creative Commons License
JAVA가 마침내 GPL로 공개됐다.

많은 사람들이 오해하는 사실 중의 하나는 "지금까지 썬에서만 배포하고 있던 JRE/JDK를 마음대로 배포할 수 있을 것이다"라고 생각한다는 것인데... 그것은 사실과 다르다.

소스가 GPL이 된것이지 JRE/JDK의 설치 패키지가 GPL인 것은 아니기 때문이다. 다만 썬이 공개한 소스를(GPL에 의거하여) 컴파일하고 나름대로 패키징해서 배포하는 것은 무방하다.

비유하자면, RHEL는 GPL이지만 레드햇이 지정된 경로를 통해서만 배포할 수 있지만, 레드햇이 공개한 소스를(GPL에 의거하여) 컴파일하고 나름대로 패키징해서 나름대로의 이름으로 배포하는 ?CentOS같은 변종들이 있는 것과 같다.

단, 이 과정에서 썬이 공개한 소스에 수정을 가했다면, 그 소스도 GPL로 공개해야한다.

소스를 볼 수 있고, 수정할 수도 있지만, 수정된 소스를 오직 썬을 통해서만 배포할 수 있었던 것에 비하면 진일보 했다고 할 수 있지만, 소스는 이미 여러가지 경로로 입수 할 수 있었기 때문에 정치적인 의미를 제외하면 그다지 큰 변화라고 보기는 힘들다. 적어도 개발자들 입장에서는 그렇다.

GPL로 바뀌었으니, 윈도나 리눅스 배포판에 기본으로 포함될 것이라는 섯부른 기대는 당분간 접어두는 게 좋을 듯...

그러나, IBM이나 여타 벤더들이 썬의 자바 소스를 나름대로 수정한 패키지를 마음놓고 배포하겠지. 게다가 그 녀석들은 나름대로의 확장을 추가했을테고...(IBM은 이미 썬의 허락하게 그 짓을 해오고 있었다.) 어쩌면 머지않아 SWT가 기본으로 포함된 IBM의 JDK/JRE를 볼 수 있을지도 모른다. 이것이 썬이 걱정하는 것들이다.

결국, 썬은 명분도 잃고 실리도 잃는... 말하자면 개삽질을 한 것이다. 늘 그랬던 것처럼... -.-;

썬의 자바 소스를 수정해서 motif를 걷어내고 GTK로 바꿔서 빌드해서 배포해 볼까? 예전에 하다만 것이 있긴 한데... 그것도 필요 없을 듯~ 그냥~ classpath의 것을 가져다 쓰면 되니까 ;)

'hacking > java' 카테고리의 다른 글

XML Exodus...  (3) 2007/01/07
아니~ 버~ㄹ써! Java6~  (0) 2006/12/12
Java, finally GPLed  (0) 2006/11/14
Java Browser Edition?  (0) 2006/09/08
mustang beta released  (0) 2006/02/16
maven2 유감...  (0) 2005/12/07
Posted by iolo
TAG GPL, Java
hacking/java2006/09/08 11:11
크리에이티브 커먼즈 라이선스
Creative Commons License
?JavaKernel 이라는 이름으로 Java7에 포함될 듯...

말하자면, "처음으로" 애플릿을 실행하기 위해 필요한 런타임(JRE 플러그인 버전)의 용량을 줄이기 위해 rt.jar를 쪼개고, 그걸 on-demand로 다운로드 할 수 있도록 한다는 얘기다.

현재 Java6 런타임이 15M정도인데, 이렇게 하면 콘솔 버전 HelloWorld 정도를 돌리는 데는 2.6M, AWT 버전을 돌리는 데는 3.5M 정도면 된단다.

멋지군! 멋져!

그런데... 자바가 찬밥을 먹는 것이 런타임의 크기 때문일까? 크기 때문에... 윈도를 설치할 때 플래시와 함께 설치되지 않는 걸까? (조만간 리눅스는 gcj/classpath가 기본 설치될 것 같지만...) 주변에서 OSX을 쓰는 사람들을 살펴보면 (클래식부터 써온 x신도들은 예외지만) 별 느낌없이 자바 어플리케이션을 쓴다. 대부분은 그게 자바 어플리케이션이라는 사실을 알지도 못하고 관심도 없다.

?JavaKernel이 도입되었을때의 반응을 예상해보자.

  1. 애플릿 발견! JRE 플러그인을 다운 받을래요?
  2. yes (다들 고민하지 않고 yes를 누른다.)
  3. 다운로딩... 끝! o (여기가 과거와 달라진 부분이다. 과거엔 프로그래스바를 잠깐 쳐다보다가 cancel을 하는 사람들이 꽤 있었다.)
  4. 멋드러진(!) 스윙 어플리케이션이 뜬다! 차례... 차례... -.-? (이것이 과거와 또 달라진 부분이다. 과거엔 여기까지 왔으면 바로 퍽~ 떴다.)
  5. 맘에 들진 않지만... 여기까지 왔으니.. 이것 저것 클릭해본다. 꿈뻑... 꿈뻑... -_-;;; (?SwingSet을 봐라. 로컬에서도 그렇게 차례 차례 뜨는데, 다운로드까지 하면.. 볼만하겠다.)
  6. "back" 또는 "stop" 또는 창 구석에 있는 "x"를 과감히 눌러준다.
  7. 방금 JRE 플러그인을 깔았다는 사실을 잊어버린다. 하지만 "자바는 ugly하다"는 사실(?)은 확실히(!) 기억하고 있다.

기본적으로 다운로드하는 전체 크기는 달라지지 않는다. 다만 나눠서 받을 뿐이다. 여기에는 두 가지 측면이 있다:

  • pros: cancel을 누를 맘이 들 정도로 길게 끌지 않는다.
  • cons: (수시로 짧게 짧게 시간을 끌다보면) close를 누르고 싶은 충동을 느낀다.

솔직히 말해서, 난 ?JavaKernel 같은 거 필요없다. 그거 말고... 한번 설치하고 나면 버전업이나 자동으로(수동이라도 좀 쉽게)해줘라. 지금 업데이터는 설치 제거 후 재 설치... 즉 자동 다운로드에 다름아니다. SUN! 니네들은 apt나 yum같은 거 안 써봤냐? maven은 쓸꺼 아니냐? 제발 삽질 좀 하지마라. 정치나 좀 잘해서.. 윈도나 리눅스도 맥처럼 기본으로 깔려나오게 해 줘라. dell이랑 hp에 번들해 넣었다고? 애써 정치를 했으면 마무리 좀 해라. 번들하면 뭐하냐~ 기본으로 설치도 안되는! 쳐다보지도 않는! 추가 CD에 쳐박혀 있는데... 그리고, JRE 1.3은 없느니만 못한거 아냐? 애초에 안깔려 있으면 다운받아서 깔 생각이나 하지. 5년전 버전을 깔아놓고는 "어라, 자바 깔려있는데 왜 안되지..." 이런 반응 들어본적 없냐? 그러게 업데이트를 좀 더 똑똑하게 만들었어야지... 주변에 물어봐라... JRE가 자동 업데이트(다운로드) 된다는 사실을 알고 있는 사람이 얼마나 되는지...

'hacking > java' 카테고리의 다른 글

아니~ 버~ㄹ써! Java6~  (0) 2006/12/12
Java, finally GPLed  (0) 2006/11/14
Java Browser Edition?  (0) 2006/09/08
mustang beta released  (0) 2006/02/16
maven2 유감...  (0) 2005/12/07
neat flash demo java studio creater  (0) 2005/11/22
Posted by iolo