Tuesday, July 28, 2009

「自由にどうぞ」라고 하는 포스트잇

어제 퇴근하려고 타임카드를 찍으려는데, 타임카드 앞에 「オペミスをなくそう」라고 하는 기사를 복사해서 「自由にどうぞ」라고 하는 포스트잇을 붙여놓은 것이 놓여 있어서, 퇴근하는 전철에서 읽었습니다.

이런 일은 제가 이 회사를 다니면서 처음 있는 일이었습니다.
작은 것이지만, 한국처럼(한국도 잘 안하긴 하지만) 동료끼리 물어보면 잘 알려준다던가, 새로운 것을 발견하면, 식사를 같이하면서 얘기하며 정보를 나눈다던가 하는 것이 전혀 없는 굉장히 삭막한 분위기의 일본회사 시스템본부 였기 때문에,

정말 이상하게 들릴 이야기일지 모르지만...
굉장히 흘겨쓴 글씨인 「自由にどうぞ」라고 하는 포스트잇에 전 「감동」받았답니다.

크-


기사는 Nikkei Systems 2009년 8월호 특집 이었습니다.

Monday, July 27, 2009

stackoverflow.com의 경험

최근에 Aero님을 통해 알게된 개발자의 지식인 사이트에 해당하는 stackoverflow.com을 이용하는 일이 많았습니다.
꽤 사이트가 충실히 운영되고 있다라고 할까요. 원하는 내용을 검색해 나온 결과로 메일링 리스트나 뉴스그룹에 포스팅 된 글일 경우,

질문입니다 어쩌고 저쩌고
RE:질문입니다 어쩌고 저쩌고
RE:질문입니다 어쩌고 저쩌고
RE:질문입니다 어쩌고 저쩌고
RE:질문입니다 어쩌고 저쩌고
RE:질문입니다 어쩌고 저쩌고
RE:질문입니다 어쩌고 저쩌고

와 같은 thread로 된 자료들은 자료를 찾기 어렵습니다. 내가 찾는 답변이 어느 post에 있는 지 운이 나쁘면 전부 다 열어서 확인해 보아야 하는 경우도 있구요.

그런데 stackoverflow.com은 자료를 찾기 쉬웠고, 특히, 그 질문과 답변의 질이 상당히 좋습니다.
로그인도 OpenID를 사용하고 있구요.

그래서 최근 많이 이용하고 있었습니다만, 아직 저는 추천을 클릭할 수 있는 레벨이 아니었습니다. 추천은 최초 15 reputation point를 얻어야 할 수 있습니다.
나도 추천에 참여하고 싶었습니다만, 좀 아쉬웠지요. 하지만 reasonable한 정책이라고 생각하기 때문에 어쩔 수 없었습니다.

___


그러던 중, 최근, 어떤 문제를 해결하기 위해 한참 씨름하고 있다가 결국 내가 원하는 해결방법을 경험한 사람은 Net상에 적혀있지 않다라고 결론을 내리고,
용기를 내어 stackoverflow에 글을 써보았는데 굉장히 신기한 게시판을 경험했습니다.

뭐랄까. 요즘 외국의 사이트에는 거의 다 있는 post에 투표하기, 그리고 자신의 포스트에 얻은 reputation(명성) 점수로
뱃지가 주어지며 (현재 저는 11점이며 student 뱃지입니다.) 뱃지가 매우 높은 유저는 낮은 유저의 post를 편집해 버릴 수도 있습니다.(이부분이 제일 쇼킹했습니다.)

원래의 글은

hi all.

I am struggling to get control of an IE preview control which is 'Internet Explorer_Server' class on an external windows application with perl

I can get a handle of that 'Internet Explorer_Server' with Win32::GUI::GetWindow(), but have no idea what to do next.

Any help would be greatly appreciated!
Thanks,
Kim

였습니다만, 7,386 reputation point를 가진 Sinan Ünür라는 사람이 'hi all.'과 'Any help would~' 부분을 떼어버리고,
타이틀도 수정해 버려서 깜짝놀랐습니다. 그런데 이게 순식간에 이루어진 일이었습니다.
내가 글을 post하고 submit한 뒤에, 30초쯤 있다가 잘 올라갔는지 확인하기 위해 보니, 내가 쓴 제목이 아니었습니다.

그리고는 질문이 코멘트로 달려 있었습니다.

Can you clarify what *Internet Explorer_Server* is? – Sinan Ünür

그래서 답변을 했지요.

Internet Explorer_Server is the class name of the window, I've found it with Spy++. and here’s my assertion code of it $className = Win32::GUI::GetClassName($window); if ($className eq "Internet Explorer_Server") { ... } – crowdy

그랬더니 이번에는 Manni라는 사람이 제 원래의 post에 제가 답한 코멘트의 코드를 더해 자세한 하나의 문장으로 편집해버리는 것이었습니다.

6번의 수정을 거쳐, 제목, 내용 flag 몽땅 적당한 것으로 추가, 편집되고, 사이트에 손색이 없는 포스트로 만들어져 버렸습니다.
post의 Title도 제가 쓴 것은
How to NAVIGATE an external Internet Explorer_Server class with perl

이었습니다만, 최종적으로
How can I automate an existing instance of Internet Explorer using Perl?

로 수정되었습니다.

___

일본에도 「教えて」등의 질문 답변 사이트가 많아지고 있습니다. 저희 그룹의 어느 회사에서도 그런 사이트를 하나 기획하고 있다라고 들었습니다.
하지만 아직 이러한 형식은 한국과 일본에서 시도되고 있는 것 같지는 않습니다. 그도 그럴것이 타인의 post를 수정하다니, 아주 Technical한 분야나, 수학, 과학등 Solution 또는 객관적 Information의 성격을 지닌 분야에서나 적용이 가능하겠지요.

응용한 기획을 생각해 볼 수도 있겠다는 생각이 들게하는 꽤 재미있는 경험이었습니다.
#결론으로 아직 원하는 solution은 못찾았습니다.
___


이상.

Tuesday, June 30, 2009

[정보공유]「log4sql」의 소개

[정보공유]

[산소]로부터의 정보공유입니다.
java의 DAO계층에서 Statement로 쿼리를 부르는 경우, 정확히 어떤 쿼리가 전송되는지 로그를 남기도록 driver를 proxying하는 driver, 「log4sql」의 소개입니다.

http://log4sql.sourceforge.net/index_kr.html

한글, 일어의 페이지가 있습니다.(만, 일어페이지는 좀 깨져있군요)

비슷한 것으로 p6spy가 있습니다. p6spy가 더 많은 기능을 탑재하고 있다고 생각합니다만, 라이브러리 평가페이지 jars.developer.com에서 Top 25% Rated의 평가를 받고 있네요.
살펴볼만한 가치가 있다고 생각합니다.

이상.

Sunday, June 28, 2009

best practice of designing DAO

best practice of designing DAO

지금까지의 경험을 정리하는 것입니다만, DAO의 구축에 대해 한 번 알고 있는 모든 것을 동원해 "어떻게 하는 것이 좋은 지"에대해 한 번 생각해 보고자 합니다.
Database를 이용하는 우선 설계의 방식에는 여러가지가 존재할 수 있습니다. 각각 모두, 요구되는 '기록과 열람'이라는 내용은 만족합니다. 그러나 어떤 것이 왜 좋은지 알 지 못한다면 곤란합니다.

우선은 기본적인 Data의 설계는 각 프로젝트별로 맡기고, 여기에서는 공통적으로 다루어야 할 issue에 대해서만 촛점을 둡니다만, DB의 모델링에 대해서는 다양한 시스템에 대한 설계의 경험을 쌓아야 합니다.

각 프로젝트별로 필요한 필드의 추출, 추출방식은 도메인 모델을 기준으로 하던지, use case를 기준으로 해도 문제가 되지 않습니다. 또한 generalizing과 degeneralizing도 어느쪽에 비중을 더 크게 두더라도 틀린 것은 아닙니다. 오히려 어느쪽에 비중을 더 두었는 지를 보고, 어떤 기능이 들어가는지 기획을 짐작할 수 있습니다.
리소스에 여유가 있다면, Fetch용 Database와 DML용 Database를 따로 두는 것도 가능합니다. 이런 경우의 Database의 설계는 일반적인 경우와 많이 다른데, 일반적인 경우만 다루어본 사람이 이러한 구조를 알지 못한 채, 이런 ERD를 만나면, "DB를 잘 알지 못하는 사람이 작성했나보군"하고 생각할 지도 모릅니다.

공통적으로 다루어야할 Database의 설계에 대한 Issue로 여기고 있는 것은 다음과 같습니다. 안전한 Data의 취급이 무시되어야 하는 시스템은 없을 것입니다.
다음에 적는 것들은 없어도 기록의 출입을 구성하기에는 문제가 없습니다만, 고려해 보아야 할 내용들입니다.

1) Optimistic Lock
2) Trigger를 이용한 Update Delete시의 Transaction Table에의 기록.
3) Procedure를 이용한 DML(plus DML query의 실행제한)

Optimistic Lock은 시스템의 구성에 따라 꼭 필요하기도 하고, 없어도 상관없는 경우가 있습니다. Transaction의 기Term이 긴 시스템이라면 반드시 필요합니다. 구현은 프로시저를 사용하지 않고 코드에서 구현한다면, 상당한 작업량이 될 수 있습니다. 만일 프로시저를 사용할 수 없다라면, OR-Map의 도입도 고려해 보는 것도 좋다라고 생각합니다.

Trigger를 이용한 Transaction을 Table에 기록하는 것은 고객의 동작을 기록해 놓는 것으로 , 안전성의 의미가 큽니다.

Procedure를 이용한 DML은 parameter check도 코드에서 하는 것이 아니라 procedure에서 하겠다는 얘기입니다. Data기록의 로직은 Database의 Procedure에 두겠다는 것은 한 가지 언어 이외에도 복수의 언어로 구성된 시스템에서 동일한 기록의 동작을 보장합니다.

이것은 DB에 매우 큰 로드를 걸지 않는 한, 매우 바람직합니다라고 생각됩니다만, 실제로 많이 사용되는 경우는 보기 어려웠습니다. 특히 Procedure를 사용하지 않고, Application서버가 여러대로 분산되어 있을 경우 부하를 DB보다는 Application서버에 두려 하는 경우, 또 OR-Mapper를 더 선호해서 이를 통한 DML 작업을 하는 경우가 이유로 많이 제시되곤 했습니다.
그러나 잘 생각해보면, Hibernate등의 OR-Mapper를 사용한다고 하더라도 Select에 대한 작업은 Cache Provider등을 사용해 이득을 볼 수 있지만, Insert Update Delete에 대한 작업이 그리 많이 이득을 볼 수 있는 시스템이라고 확실히 얘기할 수 있는 시스템은 많지 않은 것 같습니다.
Hibernate등을 선호하는 케이스라면, 시스템이 허용하는 한, 사용해도 좋다고 생각합니다.
이런 경우라면 insert update delete 명령어를 금지하면 안되겠지만, DBA계정이 아닌, Application이 사용하는 계정이라면 금지를 생각해보는 것도 가능할 지 모릅니다.(실제 그렇게 운영해 본 적은 없습니다만...)

아아.. 오늘은 이만 해야겠습니다.
이 문서는 완전한 것이 아니므로 추가될 것입니다.

Saturday, June 20, 2009

Today, I kicked a small project off for me.

오늘 부터 작은 실험을 시작하려고 합니다.
어떤 실험인가 하면, 가끔 적는 이 블로그에, 한글은 물론, 일본어와 영어로 적어보려고 합니다.

제가 적는 블로그는 회사의 업무시간 가운데에 적는 것이 많습니다.(그래서 매우 단편적이면서, 깊지 않은 내용들이 많습니다.)
그렇기 때문에 처음에는 하나의 언어로만 적어두었다가 나중에 나머지 언어의 내용을 추가해 적는 경우도 있을 것입니다.

이상한 문장도 많이 쓰고, 뜻이 잘 못 전달 되는 경우도 있을 것입니다.
하지만 몇 년 꾸준히 계속하면 큰 공부가 될 것으로 기대합니다.

방문해 주시는 분께는 한가지 부탁으로, 잘 못된 문장을 지적해 주시면 제게는 큰 공부가 될 것입니다.
아무쪼록 잘 부탁드립니다.

====

今日から自分のためにひとつの小さい実験を始めようと思います。
どんな実験なのかというと、たまに書くこのブログに、ハングルは勿論、日本語と英語も一緒に書いて見ようと思います。
私の書くブログは会社の業務時間の中に書くことが多いです。(それで非常に断片的だし、深くない内容が多いです。)
そうだから初めには一つの言語でだけ書き留めてから後で残り言語の内容を追加して書く場合もあるでしょう。

変な文章もたくさん書いてしまい、意味がよく伝えられない場合もあるでしょう。
しかし何年弛まず続けば大きい勉強になることで期待します。

訪問していただいた方にはひとつお願いがありまして、間違った文章を指摘していただければ、私には大きい勉強になると信じています。
なにとぞよろしくお願いいたします。

====

Today, I kicked a small project off for me.
to say what it is, it is writing my blog posts with Hangul (of course!), japanese and english at once.

I usually write my posts in working time( that's why they are piecemeal and outline-like)
so I might publish posts written with one language and add other languages later.

sentences will be wrong and ridiculous.
but I will hang on it for years and it will be a good study

to visitors, please leave your comment for me.
your little advice for my wrong english is great help
thank you.

Friday, June 19, 2009

groovy cgi

groovy파일을 cgi로 이용해 사용하는 장난(?)을 하다가, parameter를 받는 작업을 하던중, 제대로 처리하게 하지 못해서 애를 좀 먹었습니다.
한글이나 일본어가 깨지는 현상때문이었는데요. 파일도 utf-8(without BOM), 그리고 groovy.exe의 실행옵션에서 도움말에 있는 --encoding UTF-8 이나 -c UTF-8을 아무리 주어도 제대로 표시되지 않았습니다. 아파치의 설정이 잘못된 것인지도 보고, 옵션이 먹지 않는지 레지스트리의 .groovy파일 실행할 때 디폴트 옵션을 줘보기도 했습니다만, 해결은 다른 방법으로 되었습니다. 옵션에 -Dfile.encoding=UTF-8 을 주고 실행하는 것이었습니다.

아마도, 스펙대로라면 -Dfile.encoding=UTF-8 이 없어도 잘 표시되어야 할 것 같은데...., 잘 되지 않았습니다.


#!C:\Progra~1\Java\groovy-1.6.0\bin\groovy.exe -Dfile.encoding=UTF-8
//C:\Progra~1\Java\groovy-1.6.0\bin\groovy.exe -c utf-8 -D file.encoding=UTF-8

import java.net.URLDecoder;
def decoder = URLDecoder;

print "Content-type: text/html\n\n"
print "<html><head><meta content='text/html; charset=utf-8' http-equiv='Content-Type'/></head><body>"
def name='World'; println "Hello $name!"

/* == to show all env variables
def env = System.getenv()
for(k in env){
println(k)
} */

def __form = [:]
def arrykeyvalue
def strQueryString = System.getenv()['QUERY_STRING']
if (strQueryString != null) {
def arryForm = strQueryString.split('&')
arryForm.each {
arrykeyvalue = it.split('=')
__form.put(arrykeyvalue[0], arrykeyvalue[1])
}
}

__form.each {
print (it.key + ' = ' + it.value+ '<br>')
}

__form.each {
print (it.key + ' = ' + decoder.decode(it.value, "UTF8") + '<br>')
}

print "日本語 <br> "
print "한국어 <br> "
print "</body></html>"



html 태그가 있어 본문에 에러가 있다고 하니 일본어의 전각 괄호로 바꾸었습니다.
그리고 아래가 실행 내용입니다.




Wednesday, June 17, 2009

[정보공유] 윈도우즈환경에서 groovy로 cgi하기

최근에는 perl 프로젝트를 하고 있는 영향도 있지만, cgi의 재발견이랄까 재미를 느끼고 있는 것은 사실입니다.
도메인이니, 모델이니, DAO니 BL이니 하는 라이브러리를 만들고 난 뒤 여러 복잡한 프레임웍의 설정과 웹어플리케이션의 설정을 하고 나서야 페이지 하나를 볼 수 있는 엔터프라이즈급의 개발은 분명 가벼운 마음으로 할 수 있는 것은 아닙니다.
작은 프로그래밍을 가벼운 마음으로 해보기 부담스러운 것은 grails, gsp도 마찬가지에요. 그런의미에서 cgi는 상대적으로 부담이 적기 때문에 작은 프로그래밍을 해보기에는 적합합니다.

groovy로 cgi를 하는 방법은 전에도 한번 시도해보았었습니다만, 윈도우즈환경은 리눅스와 달리 groovy.bat 파일로 실행되는 결과를 output으로 보내기에는 적합하지 못했습니다. 왜냐하면 아파치 프로세스가 cgi용 파일을 만나면 그 파일을 열어 Shebang #! 을 보고 어떤 명령을 실행해서 값을 구할 지 처리하는 과정에서, cgi용 파일에 groovy.bat로 해석하라고 전달하게 되는데 ,
아파치 process가 groovy.bat test.goory 명령을 실행하면, 그 프로세스에 output이 return되어 지는 것이 아니라, bat파일을 해석하기 위해 %comspec%가 실행된 다음 그 프로세스안에서 다시 jre를 실행한 뒤 결과값인 output이 나오기 때문에, bat를 실행시킨 process에서는 output을 구할 수 없기 때문입니다.
Shebang을 사용하지 않고 AddHandler나 Registry에 Associated Application을 설정한 경우에도 잘 되지 못했습니다.
이야기가 길어졌습니다만, 결론은, 윈도우에서 제대로 groovy파일을 cgi로 사용하지 못했다. 라는 이야기 입니다.

반면 아마도 리눅스 환경에서는 -시도해 본 일은 없습니다만 - 아파치프로세스가 groovy 쉘 스크립트를 실행하여 output을 얻는 것은 특별히 문제가 되지 않을 것 같다는 생각이고, 또 그렇게 했다는 블로그를 본 적도 있습니다.

=============

그런데 최근 잠깐 살펴보니 Native Launcher 라는 것이 등장해 있었군요.
http://groovy.codehaus.org/Native+Launcher
groovy.exe를 바로 다운받을 수 있는 링크도 있습니다.

왜 groovy.exe를 사용해야 하는지 적어놓은 부분도 있습니다만, 여기에는 cgi 이야기는 없군요. (원래 할 수 있는 것을 제가 못해낸 건지도 모르겠습니다.)
어쨌든, 이 groovy.exe로 cgi설정을 해보았습니다. (apache와 groovy까지는 설치되어 있다고 가정합니다.)

groovy.bat 파일을 groovy.bat.old 로 옮기고,

httpd.conf 안에 LoadModule이 끝나는 곳에 다음 한 줄 추가

setEnv GROOVY_HOME c:\Progra~1\Java\groovy-1.6.0
(또는 PassEnv GROOVY_HOME 해도 되나요. 확인해 보지 않았습니다.)

그리고 .groovy파일 더블클릭하면 groovy.exe파일이 실행되도록 설정해 놓고. AddHandler는 특별히 추가하지 않았습니다.

그리고 다음과 같이 test.groovy cgi를 하나 만들고

#!C:\Progra~1\Java\groovy-1.6.0\bin\groovy.exe
print "Content-type: text/html\n\n"
def name='World'; println "Hello $name!"

실행해 보았습니다.


-_-)=b

HtmlBuilder까지 사용하는 것은 무난할 것 같습니다.

#!C:\Progra~1\Java\groovy-1.6.0\bin\groovy.exe
print "Content-type: text/html\n\n"

def writer = new StringWriter()
def builder = new groovy.xml.MarkupBuilder(writer)
builder.html(){
head(){
title("Groov'n with Builders"){}
}
body(){
p("""Welcome to Builders 101. As you can see
this Groovlet is fairly simple.""")
}
}
println writer.toString()


하지만 servlet이 아니므로 request나 response등의 객체는 사용할 수 없습니다. (사용하게 하려면 매번 web.xml을 읽어 ServletConfig를 new 하고, Servlet을 new하고... 해야 할 것 같습니다.)

앞으로 CGI방식으로 %ENV%에서 값을 받아오는 Method나 Class를 만들어보죠.