jython 문자열 과 java 문자열

요즘 본격적으로 hbase, mapreduce 로 프로젝트를 수행중인데, 일부 프로그램은 python 스크립트로 짜서 소스를 그때 그때 수정할 수 있게 해야 하는 것이 생겼다. 이렇다 보니 jython을 사용하게 되었는데, 이거 우습게 봤다가 아주 낭패를 봤다. python 과 java 사이의 glue 역할을 하는 부분을 잘 모르니 java 와 jython 간의 내부 문자열 변환에서 상당히 애를 먹었다.

일단 jython의 기본 문자열은 python의 str 타입이다. java 는 당연히 java.lang.String 이고.

문제는 HBase 관련 api 를 호출하게 되면 이 녀석들의 반환 값이 byte[] 인 것이다. 요걸 jython 에서 사용하려면 일단 java.lang.String 으로 바꾼다.

import sys

import java.lang.String

:

value_from_hbase = some_function_using_hbase_api()

test = java.lang.String(value_from_hbase, encoding_of_byte_array)

print test

byte[] 형인 value_from_hbase 를 encoding_of_byte_array 인코딩으로 java.lang.String 객체를 만들었다. 여기까진 좋다.

요걸 그대로 print test 를 하면 한글이 깨져 출력된다.

한 단계를 더 거치도록 한다.

import sys

import java.lang.String

from org.python.core import PyString

:

value_from_hbase = some_function_using_hbase_api()

test = java.lang.String(value_from_hbase, encoding_of_byte_array)

test = PyString(test).encode(encoding_of_byte_array)

print test

이제 한글이 제대로 찍힐 것이다.

신대륙이라…

예약 구매로 아이폰을 신청하고, 지난 12월 1일에 개통을 해서 사용하기 시작했다. 처음 3, 4일은 아이팟 터치에 전화기 붙었네… 약간 실망. 일주일 즈음엔 KT의 데이터 요금제 덕분(요금제 자체에 데이터 정액 요금이 들어있어, 쓰나 안쓰나 돈이 나감)에 무분별하게 사용하기 시작한 무선 인터넷 환경에 놀라움을 금치 못하게 되었고, 이주일 즈음엔 무선 인터넷, GPS, 카메라를 활용한 다양한 앱스토어의 어플리케이션들에 경악을 하게 됐다. 요런걸 만들어봐야지 하고 머리속으로 생각만 해 뒀던 서비스들이 이미 아이폰이 먼저 사용된 나라들에서는 활발히 서비스 중이다. 이 무선인터넷, GPS, 카메라의 삼단 콤보는 정말이지 엄청난 혁신을 일으킬 것 같다. 아이폰이 질러놓은 스마트폰의 하드웨어, 데이터 요금제 경쟁 덕분에 내년부터는 다양한 스마트폰들이 저렴한 데이터 요금제와 더불어 대량으로 풀릴 것이고, 이는 콜럼버스의 신대륙에 버금가는 엄청난 시장을 열어줄 것이다.

내 아이디어들을 실제로 구현하기에는 이미 시간이 턱없이 촉박한 걸 알았다. 시작이 반이다. 위기는 곧 기회이다.

잘 써지나요???

하핫 아이폰이 생기니 이거 아무데서나 블로그질을 할 수가 있구나 ㅋ
사진도 찍어서 바로 올릴수 있고 세상 참 좋아졌네


오늘 집앞 화훼단지 가서 사온 선인장들 예쁘다

iPhone 에서 작성된 글입니다.

CLASSPATH, HADOOP_CLASSPATH

HBase를 다루는 MapReduce 프로그램을 작성하다 보니 job이 할당되고, task가 뜨다가  org.apache.hadoop.hbase.mapreduce.TableMapper 가 NoClassDefFoundError 라는 메시지를 출력하고 task가 종료되어 버린다. 한동안 손을 놓고 있다가 오랫만에 다시 보니 이거 참 새롭다. 분명히 전에도 저런 문제가 있어서 한참 끙끙댔던 기억이 난단 말이다.

classpath 문제이다. hbase.jar 를 못찾는 것인데, HADOOP_CLASSPATH  에 정의를 해 주면 된다. 일반 java 프로그램의 library 경로 지정은 CLASSPATH  환경 변수에 한다. MapReduce의 task 프로그램이 사용하는 classpath는 HADOOP_CLASSPATH이다.

문제는 이걸 알고 있지만서도 자꾸 나중에 끙끙대게 되는 것이다. 먼저 관련 문서를 참고 하자. http://hadoop.apache.org/hbase/docs/current/api/org/apache/hadoop/hbase/mapred/package-summary.html#package_description

이걸 보면 HBase 를 다루는 MapReduce 프로그램은 hadoop/conf 디렉토리에 hbase-site.xml 파일을 넣고 hbase.jar 를 hadoop/lib 디렉토리에 복사한다. 보다 확실한 방법은 hadoop/conf/hadoop-env.sh에  HADOOP_CLASSPATH 에 hbase.jar 와 hbase/conf 디렉토리를 추가하는 것이라 나와있다. task 프로그램이 사용하는 그 외 기타 라이브러리의 경로도 여기에 추가해 주면 된다. 그런데 hadoop-env.sh 의 HADOOP_CLASSPATH 값은 실제 값이어야 한다. .bashrc 같은 파일에 환경변수 값을 설정하고 hadoop-env.sh 에서 이 값을 가져다 쓰는 식으로 하면 처음엔 Job이 잘 실행되는 것처럼 보이다가 정작 task 노드에서 task가 실행될때 task프로그램이 위처럼 class 파일을 못 찾고 종료되어 버린다.

실제 파일 값을 예로 보자.
~/.bashrc

:
for jar in /opt/hbase/lib/*.jar; do
  lib_path=${lib_path}:${jar}
done
export CLASSPATH=”/opt/hbase/hbase-0.20.0.jar:/opt/hbase/conf:${lib_path}”
:

/opt/hadoop/conf/hadoop-env.sh

:
export HADOOP_CLASSPATH=$CLASSPATH
:

이렇게 설정하면 안된다.

아래와 같이 실제 값을 hadoop-env.sh에 넣도록 한다. 아마 task 프로그램이 실행되면서 hadoop-env.sh 을 실행시켜서 값을 설정하는데 이용하는 것 같은데, hadoop-env.sh 안에 #!/bin/sh 없으니까 환경 변수 설정값을 못 받는게 아닌가 하는 추측이 된다.
여튼, 아래와 같이 직접 hadoop-env.sh 안에 값을 설정하도록 하자
/opt/hadoop/conf/hadoop-env.sh

:
for jar in /opt/hbase/lib/*.jar; do
  lib_path=${lib_path}:${jar}
done
export HADOOP_CLASSPATH=/opt/hbase/hbase.jar:/opt/hbase/conf:${lib_path}
:

확인해 보진 않았지만, hbase/conf/hbase-env.sh 안의 HBASE_CLASSPATH  도 같은 맥락으로 이해하면  되지 않을까 싶다.

2010.09.07 추가
hadoop-env.sh 이 HADOOP_CLASSPATH 보다 우선 순위가 높다.
즉, HADOOP_CLASSPATH 와 hadoop-env.sh 에 각각 다른 버전의 hbase-xxxx.jar 가 설정 되어 있을 경우, hadoop-env.sh 의 것이 사용된다.

subversive URL 입력 창 비활성화 문제

사용중인 OS는 opensuse 11.2 이고 여기에 탑재된 데스크탑 환경은 KDE4.3.1 이다. 11.1 버전때부터 factory repository 를 이용하여 11.2 테스트 버전을 미리 사용중이었다. 그런데 어느때부터인지 eclipse 의 일부 버튼이 마우스 클릭에 제대로 반응하지 않는 현상이 생기기 시작하더니, 이번에 11.2 정식 버전을 새로 설치한 후부터는 subversive 의 URL 입력창, 사용자 계정 입력창이 비활성화 되는 문제가 발생했다. 일부 버튼의 마우스 클릭 이벤트에 오동작 하는건 다행히 키보드 단축키로 그럭저럭 사용가능했는데, subversive의 URL 입력창 비활성화 문제는 어찌해볼 방도가 없다. 이 문제는 데스크탑에 설치된 kubuntu 9.10 에서도 마찬가지로 발생한다. 아무래도 이클립스와 GTK 라이브러리 어딘가에 문제가 생긴것 같은데 내가 해결 할 수 있는 수준의 문제가 아니고, 이것저것 시도해보다가 임시 방편으로 URL 입력창을 활성화 시키는 방법을 우연히 발견했다. 결론부터 얘기하자면 GTK 테마를 Industrial 로 사용하는 것이다.

System Settings -> General 탭 Look&Feel; -> Appearance -> GTK Styles and Fonts 에서 GTK Styles를 Industrial 로 설정한다.

GNOME 환경이 없어서 같은 현상이 발생하는지 테스트를 못해봤는데 곧 버그가 고쳐지리라 믿는다.

trac with wsgi on ubuntu

trac을 mod_wsgi 를 이용해서 ubuntu에서 동작시킬 상황이 생겨 우분투 문서를 찾아보니 mod_python을 이용해서 설정하는 문서인지라 여기에 mod_wsgi로 설정한 과정을 남긴다. 기본 방식은 예전에 다뤘던 ubuntu에서 django 설치 와 비슷하다. 저번엔 python과 apache를 연동시키기 위해 mod_python을 사용했던 것에서 mod_wsgi로 바뀐것 말고는 큰 차이가 없다.

 먼저 apache와 python을 연동 시키는 작업을 하기 위해 필요한 프로그램을 설치 하도록 한다.

$ sudo apt-get install apache2 libapache2-mod-wsgi libapache2-svn python-setuptools subversion python-subversion trac

trac 프로젝트 환경 설정을 해 보자. /srv/trac 디렉토리를 우리가 설정할 프로젝트들의 기본 디렉토리로 사용할 것이다.

$ sudo mkdir -p /srv/trac

$ cd /srv/trac

$ sudo mkdir apache sites eggs

$ sudo htpasswd -c .htpasswd username

/srv/trac 은 trac 의 프로젝트들이 설정될 베이스 디렉토리가 된다. apache 디렉토리는 wsgi 의 trac 핸들러 모듈이 저장될 위치이고 eggs 디렉토리는 이 디렉토리에 설정되는 프로젝트들이 사용할 egg cache 디렉토리이다. sites 디렉토리에는 우리의 프로젝트 관련 파일들이 생성될 곳이다.

아파치의 htpasswd 프로그램을 이용해 username 계정에 대한 패스워드를 .htpasswd 파일에 저장한다. username은 추후 이 프로젝트들에서 사용할 로그인 계정이다. 적당한 이름을 넣도록 한다.

$ sudo vi /srv/trac/apache/trac.wsgi

apache 디렉토리 안에 아래와 같은 내용으로 trac.wsgi 모듈을 만들자.

 import sys
sys.stdout = sys.stderr

import os
os.environ[‘TRAC_ENV_PARENT_DIR‘] = ‘/srv/trac/sites
os.environ[‘PYTHON_EGG_CACHE’] = ‘/srv/trac/eggs

import trac.web.main

application = trac.web.main.dispatch_request

TRAC_ENV_PARENT_DIR 은 /srv/trac/sites 아래에 다중 프로젝트를 설정할 때 사용한다. 단일 프로젝트를 설정하기 위해서는 TRAC_ENV_DIR 을 사용한다.

 $ sudo chown -R www-data:www-data /srv/trac

아파치가 이 디렉토리에 자유롭게 읽고 쓸 수 있도록 소유자를 www-data 로 변경해 준다. 우분투에서 아파치의 기본 설정은 계정 www-data, 그룹 www-data 로 실행된다. 이 계정과 그룹이 위의 디렉토리를 자유롭게 읽고 쓰기 권한이 있어야 한다.

이번엔 아파치에서 위의 디렉토리를 trac과 연동하기 위한 설정을 한다.

$ sudo vi /etc/apache2/sites-enabled/000-default

아파치의 기본 설정 파일을 열어서 아래 항목을 추가한다.

<VirtualHost *:80>
       
:
:
        WSGIScriptAlias /trac /srv/trac/apache/trac.wsgi
        <Directory /srv/trac/apache>
                WSGIApplicationGroup %{GLOBAL}
                Order deny,allow
                Allow from all
        </Directory>
        <LocationMatch “/trac/[_[:alnum:]]+/login“>
                AuthType Basic
                AuthName “trac”
                AuthUserFile /srv/trac/.htpasswd
                Require valid-user
        </LocationMatch>

</VirtualHost>

WSGIScriptAlias /trac /srv/trac/apache/trac.wsgi 는 URL /trac 에 대해서 /srv/trac/apache/trac.wsgi 를 URL 핸들러로 사용한다는 것이다.

<LocationMatch “/trac/[_[:alnum:]]+/login”> 항목은 trac의 관리자로 로그인 할 URL 에 대해 보안설정을 하는 것이다. 추후 admin 링크를 눌렀을 때 아파치 기본 로그인 화면이 나타나고, /srv/trac/.htpasswd 의 값으로 인증이 이뤄진다.

이제 trac 프로젝트를 생성해 보자

$ sudo trac-admin /srv/trac/sites/test initenv

이로써 test 라는 프로젝트를 생성 했다.

아파치를 재 시작시켜 설정을 반영하도록 하자.

$ sudo /etc/init.d/apache2 restart

이제 브라우저에서 http://localhost/trac 을 열어보자. 방금 생성한 test 프로젝트의 링크가 보일 것이다. http://localhost/trac/test 를 열어 바로 프로젝트 페이지를 열수도 있다. test2, test3, 등등의 프로젝트를 sites 디렉토리 아래에 추가로 계속 생성할 수 있으며, 이렇게 하여 다중 프로젝트를 사용할 수 있는 설정을 마친다.

물론 이 프로젝트들이 제대로 동작하고 프로젝트를 개발 할 환경을 갖추기 위해서는 subversion 의 설정이 미리 되어 있어야 한다. subversion의 설정은 좋은 참고 사이트가 있다. http://www.pyrasis.com/main/Subversion-HOWTO 를 참고하도록 한다. xmlrpc 플러그인 설정이 필요하다면 http://trac-hacks.org/wiki/XmlRpcPlugin 을 참고한다.

* reference

1. http://docs.djangoproject.com/en/dev/howto/deployment/modwsgi/

2. http://trac.edgewall.org/wiki/0.11/TracOnUbuntu

3. http://robertbasic.com/blog/trac-on-ubuntu/

4. http://www.pyrasis.com/main/Subversion-HOWTO

5. http://trac-hacks.org/wiki/XmlRpcPlugin

행복한 고민

10월엔 kubuntu 9.10이 발표된다.  11월엔 opensuse 11.2가 발표된다. 둘다 최신 버전의 KDE를 탑재한 배포판이다.

유닉스 계열 운영체제를 사용하게 되면 사용자는 선택의 자유가 무진장 많다. 크게는 어떤 배포판을 쓸 것인지, 어떤 데스크탑 환경을 사용할 것인지, 어떤 파일 시스템을 사용할 것인지, 어떤 음악 재생기를 사용할 것인지, 어떤 PIMS를 사용할 것인지 등등 너무 많아서 무엇을 사용할 지 고민이 될 지경이다. 내 경우 처음엔 선택의 폭이 너무 넓어 무척 혼란스러웠지만, 이것 저것 사용하다보니 좋아하는 환경이 생겨서 그 것만 주욱 사용해왔다.

최소 2년 이상 사용했던 것들만을 기억해보니 데비안, FreeBSD, ubuntu 순으로 바이너리 배포 환경에서 소스 배포환경으로 갔다가 다시 바이너리 배포환경으로 돌아왔다. 돌이켜 보니, 나는 잘 패키지된 바이너리를 가져다 쓰는게 좋지, 시스템 전체를 소스로 빌드하는건 체질이 아니었다. FreeBSD를 잘 사용하다가 어느 순간부터 vmware 지원이 끊기고, java를 사용해야 할 상황이 되다 보니, 아무래도 리눅스쪽을 기웃거리게 되었다. 그래서 프비와 비슷한 환경인 젠투를 잠깐 사용했었으나… 우연히 회사 후배가 건네 준 우분투 시디, 헛… 세상에나, 데비안 보다 더 게으름뱅이로 만들어주는 배포판이라니! 거의 완벽한 기본 설정으로 내가 할 일도 거의 없고 4월, 10월엔 항상 새 릴리즈를 내 놓아서 데비안을 버리고 프비로 가게 만든 따분함까지 없애주는, 이건 뭐 이제까지 사용해 본 것들 중 가장 최고였다. 그러는 중에도 변하지 않는 한가지가 있었으니, 바로 데스크탑 환경이다. 항상 그놈만 사용해 왔었는데, 이유는 주로 KDE에 대한 불만 때문이었다. 불만은 이랬다. MS 윈도우 느낌의 UI, 초창기의 QT 라이브러리 라이센스 문제, 한글 지원 문제. 그래서 난 그놈의 리듬박스로 음악을 들으며 파폭으로 인터넷을 뒤지고 그놈 터미널로 숙제를 했더랬다. 졸업하고, 회사에 입사해서 몇년을 더 일할 때 까지도 이 조합은 결코 변하지 않을 줄 알았다. 회사에서 아이팟 터치를 강매 당하기 전까지는.

그렇게 오랫동안 사용해온 이 조합이 깨진건 쌩뚱맞게도 아이팟 터치가 생기면서 부터다. 아이팟에 mp3를 넣기 위해 아이튠즈를 설치하다 보니, 음… 언젠가 부터 버전업이 안되고 있는 리듬박스와 비교가 되기 시작했다. 아… 요런 눈깔사탕 같은 음악 재생기를 쓰고 싶다!!! 뒤져보니 다들 아마록을 추천하고 있었다. 아놔… 이건 KDE잖아… 아마록 하나 땜에 KDE 관련 라이브러리들로 내 순결한 그놈 데스크탑을 더럽힐순 없지!!! 그런데 아마록도 자꾸 궁금하다. 함 깔아볼까… 이것이 시작이었고 결정적인 한방으로 인해 완전히 KDE 환경으로 넘어가고 말았으니 바로 Konsole 이다. 아마록을 깔면서 딸려들어온 Konsole을 우연히 실행해 보게 되었는데, 그놈 터미널에는 없는 요상한 기능이 있는 것이다. 이름하여 창 나누기! 한 터미널 안에서 가로 세로 창이 나뉜다. 마치 vim으로 가로 세로 창 나눠서 편집 하듯이… 더군나다 한 탭에서 타이핑 하는 내용을 나머지  탭들에게 전파하는 즉, 나머지 탭에도 동시에 입력을 해 주는 별 희한한 기능이 다 있는 것이다! 탭을 여러개 열어두고 창을 여러개로 나눈 다음 ssh로 여러 장비에 접속을 해 두고 얘기한 동시 입력 기능을 사용하면 한 탭에서 한번 타이핑한 명령을 나머지 장비에도 동시에 타이핑 해주는 것이다!!! 아… 기발한 아이디어가 KDE 곳곳에 넘쳐나고 있었다. 상용 OS를 쓰는 것 같은 기분이 들게 만드는 세련되고 잘 다듬어진 색 배치와 위젯들은 급기야 그놈 배포판인 우분투를 버리고 KDE 배포판인 kubuntu로 갈아타게 만들었다.

그런데 kubuntu엔 한가지 취약점이 있었으니, 바로 데스크탑 환경과 배포판과의 완벽하지 못한 통합성이다. 우분투 계열은 상당히 커스터마이징이 많이 된 배포판 중의 하나이다. 예를 들어 root 계정이 없다! 이런 환경에서 데스크탑 환경이 배포판과 통합이 잘 되어 있지 않으면 뭔가 설정을 바꾸기 위해서는 이것저것 직접 손으로 만져야 하는 번거러움이 따르게 된다. 그래서 우분투는 완벽하게 그놈과 통합성을 이루도록 손질을 엄청나게 잘 해놨다. 그렇지만 쿠분투는 우분투보다 후발 주자인지라 아직까지 그 경지에는 못 이른 것이다. 회사 업무를 위해 윈도우 공유폴더를 사용하기 위해 삼바 설정을 하다가 삼바 패키지와 배포판과의 통합이 완벽하지 못해 시스템  설정 프로그램에서 삼바가 원하는 대로 설정이 안되는 쿠분투에 불만이 폭발하기에 이르렀다! KDE 데스크탑과 완벽하게 통합성을 갖춘 배포판을 물색하기 시작했다.

첫번째 후보는 맨드리바였다. .com에서 돈을 받고 일하는 프로들의 손길로 매만져진 배포판의 편리함과 심미성에 이미 길들여진 나는 순수 커뮤니티 배포판은 성이 차지 않는 지경이 되었다. 음… 맨드리바 좋다. 근데 이것 저것 설정을 만지다 보니, 돈을 내고 사용해야 하는 상업용 패키지로 업그레이드 하라는 상황을 자주 만나게 된다. 끄응… 이거 은근 짜증 나네. 다른 넘을 보자 하고 찾은게 이번엔 Novell 의 opensuse 이다. 물론 이것도 상업용 배포판이 따로 존재한다. 하지만 맨드리바처럼 노골적으로 돈을 내라는 요구는 하지 않고 커뮤니티 차원의 패키지 관리도 무척이나 활발했다. 시스템은 바위처럼 튼튼하고, KDE 데스크탑 환경과의 완벽한 통합성은 아주 훌륭했다. 작년 말부터 쓰기 시작했으니 11개월 정도 되가는데 딱히 나무랄데가 없다. 녹색 계열의 일관된 배색은 상당히 예쁘고 세련된 느낌이다. 기본 시스템 패키지는 안정적으로 천천히 버전이 올라가지만, 커뮤니티에서 관리되는 xorg, KDE, open office 같은 개별 패키지들은 상당히 최신 버전으로 활발히 업데이트가 되고 있다. 앞에서 얘기했듯이 11월 12일엔 KDE4.3.1 이 탑재된 opensuse 11.2 가 정식으로 릴리즈 된다. 현재 알파 버전인 opensuse 11.2 Milestone 7 버전을 사용중인데 여기엔 KDE4.3.1이 탑재되어 있다. KDE4.1에서는 KDE3.x대의 어플리케이션과 아직 혼재 되어 있는 것들이 좀 있었다. 같은 프로그램이 3.x 대와 4.x대가 별도로 있는 것이다. 그러던 것이 KDE4.3 에 이르러서는 기존 KDE3.x 대의 어플리케이션들이 4.x 대의 라이브러리를 쓰도록 거의 다 변경이 된것 같다. 11월 12일이 아주 기다려 진다.