Java SE 6 Released

Java SE 6가 릴리즈되었습니다.

Java 개발자라면 놓치면 안되는 몇가지 중요한 레퍼런스들을 살펴보시죠.

몇가지 코멘트.

Scripting

Agile 언어들의 생산성은 충분히 입증된 사실입니다. Java를 프로젝트의 주요 언어로 채택하더라도 각종 툴들에서 사용할 Agile 언어의 필요성은 여전히 남아있습니다. 그렇지 않아도 JRuby나 Groovy를 try해보려고 계속 생각 중이었는데, Agile 언어를 좀 더 잘 지원하게 되었다는 것은 반가운 소식입니다.

Database

Apache DerbySQLite를 대체할 수 있겠군요.

Performance

address resolving 상의 성능 문제 jrockit을 사용하고 있었는데 일반적으로 Java SE 5가 성능이 더 좋다는 것은 처음 알았습니다. (적절한 벤치마크를 해보지도 않았지만.) Java SE 6는 더 좋아졌다니 다행이군요. 현재 개발하고 있는 애플리케이션도 한번 벤치마크를 해보아야할 것 같습니다. 그나저나 Java SE 6에서는 제발 gethostbyname 대신 getaddrinfo를 사용해주었으면 좋겠군요. (소스도 한번 살펴보아야겠습니다.)

JDBC 4

SQL을 annotation으로 쓰는 기능은, annotation의 full power를 활용하는 동시에, Object-Relational impedance mismatch를 어느 정도 보완하려는 노력이 엿보이는 것 같습니다. JDBC를 사용하다가 발생하는 오류는 상황별로 자동 복구하는 등의 처리가 매우 힘들었는데, (그래서 기록해두는 수 밖에 없었는데), SQLException이 계층화된 것은 매우 환영할만한 일인 것 같습니다.

그나저나, JDBC 3과의 인터페이스 호환성이 없다는 것이 상당히 짜증스럽군요. (당연히 호환된다면 JDBC 4로 나올 이유도 없을 것 같긴 합니다만.) JDBC 3과 JDBC 4 둘다 지원하기 위한 유일한 방법은 빌드를 분리해서 바이너리를 나누는 수 밖에 없는 것 같습니다. 현재 진행중인 프로젝트라면 가능한 한 Java 6과 JDBC 4로 가는 것이 편하겠죠. 하지만, 안타깝게도 PostgreSQL의 JDBC driver 외에는 아직 공식적으로 JDBC 4를 지원하는 경우가 별로 없는 것 같습니다. 적어도 MySQL Connector/JCommons DBCP의 경우에는요. PostgreSQL의 경우에도 새로 추가된 메서드들을 제대로 구현하진 않았더군요. 소외받는 JDBC 4입니다.

Java SE 6 Released 더 읽기"

제목이 없는 한국 뉴스 서비스들

뉴스 글에 제목이 있는 한국 뉴스 서비스를 찾기 힘들다. 물론 ‘제목’은 있지만, 그것을 title element로 명기하지 않은 경우를 말한다. 뉴스 서비스 별로 제목을 제대로 다는지 여부를 알아보자.

포탈

신문

방송국

title element에 제목 달기를 제대로 하는 뉴스 서비스는 극소수에 불과하다. 그나마 제대로 하던 서비스도 (조선일보) 사이트 개편하면서 제목을 없애버렸다.

title element의 중요성에 대해서는 이전의 글에서도 주변에도 누차 얘기해왔다. 상식적으로 제목을 다는 것은, 브라우저간 호환성 이슈처럼 비용 문제가 논쟁 거리가 되는 것은 아니다. 그렇다면 뉴스 글에 대한 제목을 달지 않는 것에 어떤 전략적 의의(이를테면, 검색 엔진에의 노출을 방지하기 위한 목적)가 있는 것인가.  내가 그러한 의의에 대해서 알고 있는 사실은 없으나, 설령 그것이 유효하더라도, 사용자의 모든 불편함을 감수할만큼의 이득이 있는 걸까?

제목이 없는 한국 뉴스 서비스들 더 읽기"

A Quote from "La Plaisanterie"

젊은이들이 연기를 하는 것은 그들의 잘못이 아니다. 삶은, 아직 미완인 그들을, 그들이 다 만들어진 사람으로 행동하길 요구하는 완성된 세상 속에 턱 세워놓는다. 그러니 그들은 허겁지겁 이런저런 형식과 모델들, 당시 유행하는 것, 자신들에게 맞는 것, 마음에 드는 것, 등을 자기 것으로 삼는다. ― 그리고 연기를 한다.

La Plaisanterie by Milan Kundera

A Quote from "La Plaisanterie" 더 읽기"

Anti-Pattern: Software Development Without Writing

Why We Write에서 쓰기의 중요성은 충분히 얘기한 것 같다. 소프트웨어 개발에서도 쓰기의 역할과 중요성은 다르지 않다. 하지만, 그 중요성을 인지하지 못하는 경우, 소프트웨어 개발에서는 여러가지 문제들이 발생할 수 있다. 이 글은 쓰지 않는 것이 소프트웨어 개발에 어떤 악영향을 미치는 지에 관한 개인적인 경험을 기술한다. 이 글은 소프트웨어 개발에 있어서 어떤 것을 써야하는가, 어떻게 써야하는가를 다루지는 않는다.

1. 명확하지 않은 명세(specification)

10페이지 내지 100페이지 짜리 Microsoft Word 명세 문서를 써내야한다고 주장하는 것은 아니다. 단 하나의 문장으로 쓰더라도, 명세는 글로 쓰여질 필요가 있다. 구두를 통한 명세와 그 전달은 애초에 명세가 불명확하거나, 그러한 불명확한 점을 쉽게 짚어낼 수 없고, 전달과정에서 왜곡되거나 손실되며, 이후에도 잘못된 점을 알아차리기 힘들다. 반대로, 명세가 글로 쓰여진다면, 처음부터 불명확할 가능성이 줄어들 것이며, 불명확함을 누구든 그것을 읽는 사람이 알아차리기 쉬울 것이며, 적어도 전달과정에서는 왜곡되거나 손실되지 않을 것이며, 나중에 다른 누군가가 보더라도 잘못된 점을 알아차릴 것이다.

2. 비효율적인 의사소통

구두를 통한 의사소통(직접 대면한 상태의 대화, 전화, 회의)의 커다란 단점 중의 하나는 바로 의사소통 참가자의 시간을 배타적으로 점유한다는 것이다. 의사소통이 언제 어디에서 일어날 것인지가 결정되면, 또는 이미 의사소통이 일어난 후에는, 다른 중요한 일이 있더라도 의사소통의 우선순위를 재조정하기는 매우 힘들다는 것이다. 쓰기를 통한 의사소통은 그렇지 않다. 의사소통의 참가자들은 자신이 원하는 시간과 장소를 사용할 수 있다. 우선순위의 조정이 매우 자유롭다. 물론, 구두를 통해서만 할 수 있는 활동(즉각적인 피드백, 상대방 의지의 확인 등)이 존재하기 때문에, 모든 의사소통이 쓰기를 통해야한다는 것은 아니다. 다만, 구두를 통해서만 할 수 있는 활동이 아닐 경우에는 쓰기를 선호해야한다는 것이다.

특정 시간과 장소에 국한된다는 구두를 통한 의사소통의 단점에서 파생되는 다른 문제는 바로 참여한 당사자 외에는 의사소통의 내용을 알기 힘들다는 것에 있다. 회의록을 남기는 이유는 바로 이러한 문제를 해결하기 위한 것이다. 공식적인 회의가 아니라고 하더라도 구두를 통한 의사소통을 쓰는 것은 같은 이유로 중요하다.

쓰기가 없는 구두를 통한 의사소통이 비효율적인 점을 보여주는 단편적인 예로, 한사람과 의사소통한 내용을, 다른 한 사람, 그리고 또 한 사람 이렇게 차례대로 의사소통하는 경우를 볼 수 있다. 그야말로 코미디가 아닌가.

3. 과거의 활동/결정에 대한 회고 불가능

쓰지 않는 조직해서 흔히 볼 수 있는 광경은 다음과 같은 것이다.

“이렇게 하기로 결정/생각/디자인했었는데, 실제로 반영/작업/구현을 했었던가?”

“대체 왜 우리가 그런 결정을 했더라?” “내가 왜 그렇게 작업/디자인/구현했지?”

한달 내지는 두달 만에 끝나고 다시는 쳐다보지 않을 소프트웨어 개발 프로젝트에서는 이러한 경우는 별로 없다. 하지만, 단기 프로젝트가 아니라면, 현대의 소프트웨어 개발의 특성상 환경과 요구사항은 빠르게 변화하기 때문에, 과거의 결정을 회고하고 다시 결정해야하는 경우가 자주 발생한다. 쓰지 않는 조직은 그 때마다 위와 같은 질문들을 하기 마련이다.

Anti-Pattern: Software Development Without Writing 더 읽기"

Why We Write

Introduction

쓰는 것의 가장 본질적인 이유 중의 하나는 인간의 기억력을 (일반적으로는 정신적인 능력을) 신뢰할 수 없고(unreliable), 기억은 (정신적인 활동은) 왜곡되기 쉽상(volatile)이기 때문이다. 문학의 경우에는 우리가 쓰는 것 자체나 또는 쓰는 것의 결과물을 읽음으로서 오는 어떤 종류의 카타르시스를 즐기기 위한 목적도 있을 수 있다. 소프트웨어 개발에 있어서는, 일반적으로 과학적인 연구나 엔지니어링에 있어서는 전자가 그 목적일 것이다.

쓰는 것은, 인간 능력의 한계라는 본질적인 한계에서 파생되는 문제들을 해결하고 있는데, 그 중의 가장 중요한 것들은 바로, 사고의 도구로서의 쓰기, 의사소통의 도구로서의 쓰기, 회고의 도구(기록)로서의 쓰기가 있다.

A Tool for Thinking

사고의 대상에 대한 기억이 없다면, 더 나아가서 기억력이 없다면 우리는 사고할 수 없다. 합리적인 사고의 과정은 일련의 사고 내용을 기억하는 단계를 포함한다. 대부분의 단순한 사고의 과정에서는 인간의 (한계를 가진) 기억력만으로도 충분하다. 하지만, 좀 더 복잡한 사고를 필요로 하는 경우에는 인간의 한계를 드러내기 시작해서, 사고의 과정은 끊겨버리거나, 잘못된 방향으로 나아가서 왜곡되어버리거나, 불충분 할 수 있다. 물론 그러한 한계는 개인적으로 다르고, 천재의 경우에는 그러한 어려움을 겪지 않을 수도 있으나, 일반적으로는 그렇지 않다.

쓰는 것은 이러한 어려움을 해결해주는 역할을 한다. 사고와 쓰기를 병행할 경우, 기억의 단속이나 왜곡을 막아주기 때문에, 우리는 사고의 대상과 내용, 방향을 정확히 유지할 수 있으며, 특히 과학적(또는 수학적) 사고에서 중요한, 모든 가능성을 타진하는 과정을 제대로 수행할 수 있다.

A Tool for Communication

의사소통 과정에서의 정보의 손실과 왜곡은 의사소통을 필요로 하는 모든 조직의 골칫거리다. 과학적인 연구 또는 엔지니어링에 있어서의 의사소통은 일반적으로 사고를 동반하므로 의사소통에서의 기억력이 차지하는 비중과 역할은 사고의 경우와 같다.

쓰기는 협업 사고의 도구로서만 의사소통에 작용하는 것이 아니라, 의사소통의 방식에도 관여해서 비동기적인 의사소통을 가능하게 해준다. 대부분의 구두를 통한 의사소통은 시간과 장소를 참가자들에게서 배타적으로 점유하는 동기적인 의사소통 방식이다. 동기적인 의사소통 방식은 시간과 장소를 공유하지 않는 사람은 의사소통에 참가할 수 없다는 단점을 내포한다. 물론, 참가자들의 의지를 확인할 수 있다거나 피드백이 빠르다는, 동기적인 의사소통 방식에 고유한 장점도 존재한다. 하지만, 장점만을 취할 수 없게 만드는 단점이 있기 때문에, 시간과 장소라는 자원이 부족한 현대인은 가능한 한 비동기적인 의사소통방식을 선호하는 것이 합리적이다.

A Tool for Retrospection (History, Record)

인간의 장기적인 기억력이 단기적인 기억력에 비해서 결코 더 믿을 수 없다는 것을 생각하면, 그리고 회고를 일종의 ‘장기간에 걸친 느린 사고’로 본다면, 회고에 있어서의 기억력의 비중과 역할은 사고의 경우와 같다고도 볼 수 있다.

하지만, 회고를 필요로 하는 종합적인 사고는 필요로 하는 기억들의 항목들이 더 많을 가능성이 높고, (기억들의 항목이 많으면 그들을 ‘모두’ 기억할 가능성이 낮아진다는 전제하에) 쓰기의 중요성은 사고의 도구로서의 경우보다 더 크다고 볼 수도 있다.

 

Conclusion

쓰기는 인간의 한계, 특히 기억력에 있어서의 한계를 보완하기 위한 중요한 도구다. 사고, 의사소통, 회고는 모두 이러한 인간의 한계가 제약하는 중요한 활동들이다. 쓰기는 이러한 활동을 효율적이고 정확하게 수행하는데 중요한 역할을 한다.

Why We Write 더 읽기"

Use FindBugs for Java Development

FindBugs 이클립스 플러그인은 정적 코드 분석 (static code analysis)를 통해 버그나 권장되지 않는 프랙티스들을 찾아주는 플러그인입니다. PMD, CheckStyle 등 몇가지 유사한 플러그인을 사용해보았는데, 어느 정도 설정을 조정해주어야 쓸만한 결과가 나와서, 이런 저런 튜닝을 하고 있는 중인데, FindBugs는 기본 설정으로도 결과가 좋아서, 고민없이 설치해서 써도 될 것 같습니다. PMD, CheckStyle 등을 잘 쓰는 것에 대해서는 다음에 써보겠습니다.

설치는 FindBugs update site ( http://findbugs.cs.umd.edu/eclipse )를 사용하시면 되구요. 이클립스의 프로젝트별 설정(Preference)에서 FindBugs를 활성화시켜주면 됩니다.

관련 레퍼런스는 The Last Mind 위키의 이클립스 플러그인 페이지를 참고하세요.

Use FindBugs for Java Development 더 읽기"

궤변론자의 합리성

바보를 속이는 일은 쉽다. 지혜롭지 못한 사람을 속이는 일도 어렵지 않다. 설령 어떤 사람의 주장이, 얼마간은 진리에 의존하고 상당히 합리적인 논증 과정을 가지고 있다고 하더라도, 참인 것은 아니다. 지혜로운 사람은 그러한 주장에서 잘못된 전제들과 가정, 비합리적인 논증을 발견해낼 수 있지만, 그렇지 못한 사람들은 자신의 무지함과 무능력은 보지못하고, 궤변론자의 합리성을 시종처럼 뒤따를 뿐이다.

궤변론자의 합리성 더 읽기"

Behavior-Driven Development

내게 객체 기반 프로그래밍 (Object-Oriented Programming)를 한마디로 축약하라면, 행동(Behavior)을 기준으로 도메인을 나누는(decomposition)하는 프로그래밍 방식이라고 정의할 것이다. 다시 말해, 객체(Object)는 잘 정의된 행동(Behavior)을 대표해야한다는 것이다. 행동(Behavior)이 아니라 자료(Data)를 기준으로 디자인하면, 구조화 프로그래밍(Structured programming)의 수동적인 자료구조와 그것을 조작하는 함수들의 집합이 탄생할 뿐이다. 설령 그것이 클래스라는 프로그래밍 언어 상의 장치를 사용한다고 하더라도 객체 기반 프로그래밍이라고 부를 수는 없다. (이러한 밈(meme)에 대해서는 Object Thinking이라는 책을 참고하라.)

Behavior-Driven Development라는 말을 강문식 군에게 처음 들었을 때는 이러한 객체 기반 프로그래밍의 생각을 대변하는 일반적인 개념을 가진 말이라고 추측했는데, 알고보니 정체는 그 개념을 TDD에 적용한 좁은 의미의 것이었다. Dave Astels 자신이 정의한대로 Behavior-Driven Specification 같은 용어를 썼으면 좋았을텐데 하는 생각이 든다.

설령 그렇다고 하더라도, 행동을 기준으로 하는 디자인이 맨 먼저 테스트에 적용되는 것은 상당히 훌륭한 개념이라고 생각한다. TDD를 통해서 얻을 수 있는 이점인 재사용과 테스트가 쉬운 (Reusable and Testable) 프로그램을 만드는데 있어서 객체 기반 프로그래밍의 기본 개념인 행동(Behavior)을 기준으로 한 디자인까지 할 수 있다면, 더할 나위 없이 좋을 것이다. 다만, 그것이 테스트 또는 스펙에만 머무르지 않고 실제 행동(Behavior)을 나타내는 디자인에까지 적용되어야 하겠지만 말이다.

아래는 Dave AstelsBDD에 대한 Google TechTalks 강연 내용 요약.

Unit vs. Behavior

unit: isolated focus like class, method
behavior: little fine-grained focused picses of behavior

unit should replaced by behavior
test should replaced by specification
assertion should replaced by expectation

rSpec

xunit should replaced by rSpec
assert_equal(expected, actual)->actual.should.equal expected

The Expectation API

  • equality
    • e.g. should.equal/sould.not.equal
  • counts
    • should.have(5).items
    • should.have.at.least(5).items
    • should.have.at.most(5).items
  • arbitrary block
    • should.satisfy { |obj| … }
    • should.not.satisfy { |obj| … }
  • pattern matching
    • should.match
  • arbitrary predicate
    • should.predicate (predicate? is defined on the target)
  • forced failure
    • violated(message)
  • exception
    • should.raise <exception>
  • direct class
    • should.be.an.instance.of C
  • ancestor class
    • should.be.a.kind.of C
  • interface
    • should.response.to :message

The Mocking API

just like jMock

  • creating a mock
    • m = mock(“mock name”)
  • expecting a method
    • should_receive(:name)
  • counts
    • never/once/twice/at_least_once/any_number_of_times
  • Arguments
    • with_no_args
    • with_any_args
    • with(arg1, arg2, …)
  • Return values
    • and_returns(value)
    • and_returns_consecutively([…])
  • Provide a Block
    • should_receive(:name) {
    • |arg1, args2, …|

Why Ruby?

  • Dynamic
  • Productive
  • Fun

Behavior-Driven Development 더 읽기"

Tab Mix Plus 0.3.5 Released

Firefox의 유명한 extension인 Tab Mix Plus의 0.3.5 버전이 릴리즈 되었습니다. 아시는 분들은 아시다시피, Firefox 2.0 버전을 지원하는 버전입니다.

저의 Firefox 2.0 업그레이드 계획은 다음과 같습니다.

  • 회사의 Linux 데스크탑: Firefox 2.0 릴리즈 일에 Tab Mix Plus 개발 버전과 함께 설치.
  • 집의 Windows 데스크탑: Tab Mix Plus 0.3.5 정식 버전 릴리즈와 함께 설치.
  • Windows 노트북: ‘집의 윈도우즈 데스크탑’이 성공하면 이에 따라 설치.

현재 상황은,

  • 회사의 Linux 데스크탑: 성공했으나 기존에 저장해둔 세션이 알 수 없는 이유로 복구 되지 않음.
  • 집의 Windows 데스크탑: 성공.
  • Windows 노트북: 설치 예정.

Firefox 1.5 시절에 이미지로 캡쳐해둔 Tab Mix Plus 설정 방법이 무용지물이 되어서 괴롭습니다. 이래서 게으르면 여러가지로 손해입니다.

어쨌거나, 글 쓸 게 없으니, 별 쓸데없는 글을 다 적는군요.

Tab Mix Plus 0.3.5 Released 더 읽기"