Installing Subversion 1.4 in Ubuntu Edgy Eft (6.10)

Ubuntu Edgy Eft (6.10)에서 Subversion 1.4 사용하기

I’ve been using Subversive for a while because one of my colleagues told me it’s better than Subclipse, but I didn’t see any advantage from it, uninstalled it, and installed the latest version of Subclipse.

Subversive가 좋다는 이야기가 있어 사용하다가 그다지 좋은 점을 느끼지도 못했고 UI가 불필요하게 복잡하다는 생각이 들어 설치 제거한 뒤 Subclipse 최신 버전을 설치했습니다.

Duh! I didn’t know JavaHL shared object (DLL) is not provided for Linux. I had to configure Subclipse to use SVNKit instead of JavaHL, and I got another problem! The latest version of Subclipse was using the latest version of SVNKit which is using Subversion 1.4 working copy format and therefore not compatible with Subversion 1.3. Ubuntu Edgy Eft provides only Subversion 1.3, so my working copies didn’t work anymore with the command line Subversion client because SVNKit has upgraded the version of all my working copies to 1.4. svn up fails gracefully saying that I have to upgrade to 1.4.

그런데 Subclipse를 최근에는 윈도우즈에서만 사용해 왔던지라 리눅스에서는 JavaHL 공유 라이브러리가 있어야 제대로 동작한다는 사실을 까맣게 잊고 있었지 뭡니까. 어쩔 수 없이 JavaSVN을 사용하도록 옵션을 설정했는데, 여기서 문제가 발생했습니다. 최신 버전의 Subclipse가 최신 버전의 JavaSVN을 사용하고 있어서 Ubuntu Edgy Eft에서 제공하는 Subversion 1.3과 호환되지 않는 Subversion 1.4용 working copy로 제 로컬 카피를 변환해 버린 것이죠. 덕택에 명령행에서 svn up하니 제대로 되지를 않네요.

I could just check my stuff out again and revert back to Subversive, but I chose to install Subversion 1.4 because people are saying there are several performance improvements. The following is the installation procedure I stepped on.

저장소에서 다시 체크아웃하고 Subversive로 복구하면 되는 문제였지만 Subversion 1.4에서 많은 성능 향상이 있었다고 하여 Subversion 1.4를 설치하기로 했습니다. 다음은 설치 과정입니다.

$ sudo apt-get install gcc g++ libc6-dev libapr0-dev libneon25-dev
$ tar jxvf subversion-1.4.x.tar.bz
$ cd subversion-1.4.x
$ ./configure --enable-dso --enable-javahl --with-ssl
--with-jdk=/usr/lib/j2sdk1.5-sun --without-jikes
$ make
$ make javahl
$ sudo make install
$ sudo make install-javahl

Everything has been installed, so I tried to switch to JavaHL, but there was another problem; JVM bombs out because of a bug of libapr0. We can fix this problem by building apache2 manually.

모두 제대로 설치가 되어 Subclipse가 JavaHL을 사용하도록 하려고 하니, libapr0의 버그로 인해 JVM이 죽어버리는 문제가 있네요. 이 문제는 apache2를 다시 빌드하여 해결해야 합니다.

$ sudo apt-get install dpkg-dev devscripts fakeroot
$ sudo apt-get source apache2
$ cd apache2-2.0.xx/debian
$ vi rules

Looking into rules file, there’s a sentence that sets AP2_CONFFLAGS variable. Add the following line next to the sentence and save the file.

rules 파일 안을 보면 AP2_CONFLAGS 변수를 설정하는 부분이 있습니다. 바로 아래에 다음 라인을 추가하고 저장합니다.

AP2_CONFLAGS += -D_XOPEN_SOURCE=500

Now, let’s build the new deb package and install it.

이제 새 deb 패키지를 빌드해 설치합니다.

$ cd ..
$ sudo apt-get build-dep apache2
$ debchange -n # vi 뜨면 저장
$ dpkg-buildpackage -rfakeroot -b
$ cd ..
$ sudo dpkg --install libapr0*.deb

NOTE: If you encountered a dependency error while you run dpkg --install, you will also have to install the related packages whose name starts with apache2.

만약 dpkg --install 실행 중 의존성 에러가 나면 apache2로 시작하는 이름의 관련 패키지들도 설치해야 하니 주의하세요.

At last, adding -vmargs -Djava.library.path=/usr/local/lib option in your Eclipse command, JVM doesn’t bomb out anymore when Subclipse is reconfigured.

마지막으로 Eclipse 실행 옵션에 -vmargs -Djava.library.path=/usr/local/lib를 추가하면 이제 Subclipse 설정을 바꿔도 JVM이 죽지 않습니다.

다양한 객체 지향 원칙들이 존재하는 이유

재미있게 주몽을 보고 잠깐 들어와 보니 이런 저런 다양한 글들이 Context 개체가 남발되고 있다거나, 의미의 면적이 좁은 인터페이스를 제공하거나 그에 의존해서는 안된다거나, 최소 권한의 원칙과 같은 이야기를 하고 있습니다.

다 맞는 말씀입니다만, 저는 이런 원칙들의 궁극적인 목표를 생각해야 할 필요가 있다고 봅니다. 그것은 바로 소프트웨어 개발 비용을 절감시키는 것입니다. 소프트웨어 비용을 절감시켜야 한다고들 주장한다면 보나 마나 소프트웨어 비용이 늘어났다는 뜻이겠군요. 그렇다면 소프트웨어 개발 비용은 왜 늘어났을까요? 그것은 더 복잡한 소프트웨어를 만들어 내야 하기 때문입니다. 오늘날 모든 복잡한 소프트웨어는 다른 더 작은 소위 컴포넌트라 불리우는 소프트웨어에 기반해 개발되고 있습니다. 바꿔 말하면, 오늘날의 불필요한 소프트웨어 개발 비용 지출의 대부분이 의존하는 API의 사용성 (usability) 문제 때문에 발생하고 있다고 할 수 있습니다. 사용성 나쁜 API를 노출하는 컴포넌트를 사용하면 monolithic 하게 개발했을때처럼 생산성이 떨어질 수도 있습니다.

그런데 이 API의 사용성이란 것은 사실상 평가가 어려운 광범위한 분야로, 보통 객체 지향 설계 원칙이라는 고상한 말로 포장되어 왔습니다. 개발자의 입장에서 이 둘은 동의어나 마찬가집니다.

사용성이 높은 API는 전부를 모르더라도 쉽게 기본적이면서도 실무에 필요한 핵심적인 작업을 바로 시작할 수 있고, 좀 더 복잡한 케이스를 다뤄야 할 경우 다음 단계를 쉽게 배워 나아갈 수 있도록 학습 곡선을 정교하게 제어합니다. 그 과정에서 물론 과정보 (overinformation)은 억제됩니다. 즉, 누구나 빠르면서도 자신이 모르는 사이에 발전 가능한 방향으로 원하는 바를 성취하고, 학습의 즐거움을 느낄 수 있게 해 주는 것이 API 사용성의 핵심입니다.

그렇다면 Context 객체가 어떤 문제를 갖느냐, Context 객체 자체의 도입은 API 사용성 측면에서 매우 고무적입니다. 컨테이너나 커널이 제공하는 기능을 활용하여 동작하는 비즈니스 로직이 부모 컨테이너/커널이 노출하는 최소한의 기능만을 사용할 수 있도록 해 주는 개체가 Context 의 원래 역할이기 때문입니다. 첫 번째 글에서 static 하거나 ThreadLocal을 사용한 Context 객체를 예로 들었는데, 이는 부적절한 예입니다. static 하거나 ThreadLocal 하게 작성했다는 것이 문제이지, Context 객체 자체의 존재가 잘못된 것은 전혀 아닙니다. 문제가 있다면 Context 를 제공하는 컨테이너의 역할 정의가 모호했기 때문이겠죠. 그도 아니면 컨테이너도 아니면서 주제 넘게 intrusive한 인터페이스를 제공했기 때문이겠죠. 컨테이너나 프레임워크가 Context 개체를 제공하는 것은 전혀 잘못된 일이 아닙니다.

또한, 두 번째 글에서 이야기하고 있는 다양한 Context 개체가 한 코드에서 섞여서 쓰이는 문제는 그 코드가 동시에 다양한 기능을 사용하려고 했다는 뜻을 가질 뿐입니다. 동시에 여러 가지 일을 한다는 것이 항상 잘못된 것은 아니며, 적절한 검토가 필요할 따름입니다. 오캄의 면도날을 쫓는 것은 좋은 일이지만, 의존성에 지나치게 집착하는 것도 좋은 태도는 아닙니다. 클래스 하나 때문에 수백KB 짜리 JAR 쓰는게 왜 나쁩니까? 클래스 하나를 씀으로 인해 다른 원치 않는 부작용이 생겨야 나쁘지, 대부분의 잘 설계된 컴포넌트들은 그렇지도 않습니다. 글쓴이가 HTMLPageParser 하나 때문에 SiteMesh 를 사용한 것처럼요. 문제는 하고자 하는 일에 맞는 제대로 된 컴포넌트를 선택하는 것이지, 컴포넌트를 사용하느냐 마느냐가 아닙니다.

어떤 API 를 설계할 때 결과적으로 중요한 것은, 대상 – 엄밀히 말하면 다수의 – 사용자가 그 API를 편리하게 느끼느냐입니다. API가 불필요하게 많은 기능을 제공한다 하더라도 그것이 결국 그 API를 사용하는 대상이 편하게 느끼고 결과적으로 생산성을 가져다 주면 저는 상관 없다고 봅니다. 과연 관계의 수를 줄여 결국에는 다 제공해야 할 기능을 매우 복잡한 콜 그래프를 그리게 해야 할 필요가 있을까요? 전 당연히 없다고 봅니다. Humane interface 와 Minimal interface 에 대한 논쟁에서와 마찬가지로, 사용자가 얼마나 많은 정보에 노출되기를 바라느냐에 따라 호불호가 갈릴 뿐 정답은 없습니다.

중요한 것은 특정 원칙에 집중하는 것이 아니라, API 를 사용하게 될 사람의 마음을 헤아리고 그 사람이 가장 생산성 있게 개발할 수 있도록 하는 것입니다. 또한 나아가 사용자가 감동할 수 있는 API 를 제공해 그 설계 철학이 그 사용자가 개발하고 있는 컴포넌트에 전해질수 있도록 한다면 금상 첨화겠죠. 이것은 단순히 다양한 원칙들을 고수함으로서 이루어지는 것이 아니라 다분히 사용자층의 취향과도 결부되는 복잡한 상호작용의 결과, 즉, 매우 사회적인 과정입니다.

그러므로 우리는 오늘날 컴포넌트들이 얼마나 사용자를 고려해서 개발되고 있는지 생각해 볼 필요도 있습니다. 유명한 라이브러리나 프레임워크들을 보면 사용자층도 두텁고 피드백도 활발합니다. 닭이 먼저냐 계란이 먼저냐는 질문을 할 수도 있겠지만, 적절한 원칙을 세워 개발하였고, 그 과정에서 생길 수 있는 API의 까칠한 면을 커뮤니티의 도움을 받아 다듬어 나아가는 것이 지금까지 제가 보아 온 성공한 소프트웨어의 모습이었습니다. 원칙도 중요하지만 그 뒤에는 사용자가 있다는 것, 그리고 그 사용자와 상호작용이 제대로 이루어지지 않으면 그 좋은 원칙도 아무 소용 없다는 것 또한 명심해야 합니다.

Modifying Default ulimit Values for a Normal User in Linux

Linux에서 일반 사용자의 default ulimit 값 수정

The default value of ulimit -n (the maximum number of open file descriptors per process per user) is 1024 in Ubuntu Linux. There’s no problem with this default value in my daily life, but I start to get ‘Too many open files’ errors when I test the performance of server applications which accept from 1000 to tens of thousands client connections. A super user (root) can type a command like ulimit -n 10240 to increase the default limit value, but a normal user can’t. If you are at least a sudoer, you can resolve this problem by adding the following lines to /etc/security/limits.conf file.

제가 사용하고 있는 Ubuntu Linuxulimit -n (동시에 열 수 있는 파일의 총 수)의 기본값은 1024입니다. 일상 업무를 보는데는 전혀 지장이 없지만 서버 어플리케이션을 테스트하다 보면 적게는 1000개, 많게는 수만 개의 접속을 테스트해야 할 일이 생겨 ‘Too many open files’ 에러를 볼 수밖에 없습니다. 수퍼 유저 (root)라면 ulimit -n 10240과 같이 입력하여 그 제한을 올릴 수 있지만, 일반 사용자는 불가능합니다. 이때 만약 수퍼 유저 권한을 갖고 있다면 /etc/security/limits.conf 파일에 다음과 같은 내용을 추가하여 이 문제를 해결할 수 있습니다.

trustin         soft    nofile          10240
trustin         hard    nofile          10240
www-data        soft    nofile          10240
www-data        hard    nofile          10240

The example above increases the maximum number of open files per process per user to 10240 for two users; trustin and www-data.

위의 예시는 trustin과 www-data라는 사용자의 최대 연 파일 수를 10240으로 올려 줍니다.

인생, 책처럼은 되지 않는다!

요즘 잠이 많이 부족하다.

출퇴근 시간 다 합쳐 네 시간이다. 차 안에서 자고 싶지만 계속 버스 안에서 잤더니 목도 허리도 아파서 잠도 더 이상 못자겠다. 이사를 하려고 해도 돈이 너무 아깝다. 2억 가까운 돈을 전세금으로 써야 한다니, 그 돈이 있으면 차라리 펀드를 들겠다. 결혼할 때까지 이 생활을 계속할 생각을 하면 답답해지기만 한다. 차라리 가까운 곳이 아니라면 아예 머나먼 곳으로 떠나고 싶다.

다른 시간대의 회사에서 일을 했던 전력 때문에 밤낮 가리지 않고 연락이 온다. 솔직히 열받는다. 급한 마음에 문제 생기면 메신저 메시지와 전자 메일 날라오는 것, 이해할 수 있다. 하지만 오픈 소스인데 같은 서버 개발자로서 최소한 기본적인 소스 코드와 로그 메시지는 찬찬히 읽어 보고 물어 봤으면 하는 바람이 있다. 적어도 뭔가 이상한 낌새가 있으면 로그 레벨 낮춰 보고 메시지로 소스 코드 정도는 검색해 보고 물어봐야 하는 것 아닌가. 이렇게 지내다 보니 잘 시간은 주말 뿐인데, 주말에도 시차 때문에 자려고 하면 꼭 연락이 온다. 사실 주말에 몰아 자는 스타일도 아니라 악순환의 연속이다.

그래, 사실 제일 큰 문제는 나 자신이지. 돈에 눈이 멀어 제대로 해 놓은 일도 없이 인센티브를 덜컥 받아 안중에도 없던 근무지에서 이 고생을 하고 있는 나나, 용기있게 더 이상 그 프로젝트에 관심이 없어졌다고 말하지 못하는 나나, 참 문제다. 책에 적힌 대로 그냥 그렇게 내 자신의 다시는 돌아오지 않을 수도 있는 행복을 위해 입 싹 닫고 멋대로 해 버리기엔 내 양심이 너무나 찔린다. 인생, 책처럼은 되지 않는다. 아니면 혹시 아직 책을 덜 읽은 걸까? (웃음)

배고픔의 자서전

계절 탓에 일찍 드리워진 암흑을 헤치고 나아가는 버스 안에서 쏟아지지 않는 잠을 청했다. 하지만 고단한 몸은 삶의 의미를 맹목적으로 질문하고 있었다. 아마도 낮에 읽은 ‘배고픔의 자서전‘에서 아멜리 노통브와 니쇼상이 나눈 마지막 대화 때문이리라.

“아무려면 어때? 아직은 이렇게 목숨이 붙어 있는 걸.”

미칠것 같은 공허함, 결핍, 두려움, 절망 속에서 그래도 우리는 아직 살아 있다. 죽음이 찾아오는 순간까지 그러한 감정들을 잊지도, 버리지도 못할 것이다. 그것은 아프다고 부정해 버리기에는 존재의 너무나 많은 부분을 차지하고 있는 아픔이자, 아직 목숨이 붙어 있다는 징표다.

외롭지 않다면 기댈 곳도 없다. 힘들지 않다면 쉴 곳도 없다. 공기가 희박할 수록 숨이 가빠지듯, 절망 속에 갈구하는 희망이야말로 진정 가치 있다. 삶의 다양한 극한을 경험한 그녀가 천재적 글솜씨로 전하고 싶었던 메시지는 그래서 그 기교보다도 감탄스럽다.