며칠전 스프링 3.0.4가 나왔다. 3.0.1 이후 마이너 업그레이드는 거의 자잘한 버그 수정이거나 최신 버전 서드-파티 툴 지원(확인)이 전부였는데 3.0.4에는 눈에 띄는 새로운 기능이 추가된 것이 있다. @MVC에서 세 가지를 찾아 볼 수 있다.  @ModelAttributge 모델이 아닌 단순 @RequestParam 등에서도 포매터를 사용하게 된 것과 mvc 스키마에 새롭게 추가된 전용 태그 두개이다.

3.0.4 내용을 모두 확인하고 추가된 기능 등을 토비의 스프링 3에 반영해서 다음 인쇄시 적용해 달라고 할 수도 있겠지만, 버전 업그레이드를 시도하는 것은 생각보다 부담이 큰 작업이다. 3.0.4만 해도 개발 스타일을 바꾸고 싶은 것이 있어서 예제도 손을 좀 봐야 하고. 그래서 일단 블로그에 그런 내용을 정리해보기로 했다.

 

3.0.4의 변경사항 중에서 그 중에서 가장 내 관심을 끈 것은 바로 <mvc:default-servlet-handler/>이다. 이를 이용하면 그동안 안쓰자니 불편하고 쓰자니 지저분해 보였던 UrlRewriteFilter를 제거할 수 있게 됐다. 그런데 UrlRewriteFilter 따위는 왜 쓰게 됐을까?

여러 가지 이유를 댈 수 있겠지만 가장 큰 것은 RESTful 스타일의 URL을 사용하고 싶기 때문이다. RESTful 스타일 URL의 특징의 하나는 확장자를 쓰지 않는 것이다.  기존엔 주로 컨트롤러에 매핑되는 URL을 login.do니 login.action이니 하는 식으로 특정 확장자를 주어서 만들었다. 그래서 스프링의 프론트 컨트롤러인 DispatcherServlet의 서블릿 매핑을 *.do나 *.action 처럼 주면 됐다. URL의 서브 디렉토리는 어떻게 잡아도 상관없어서 이 방식이 가장 편하긴 하다.

그런데 RESTful 스타일에선 이렇게 확장자를 잘 쓰지 않는다. 여러가지 스타일이 있지만 보통 리소스 이름을 경로로 쓰고 그 뒤에 의미있는 추가 경로를 붙이거나 HTTP요청 메소드(GET,POST,PUT 등등)를 바꿔서 활용하는 식이다. 그래서 URI가 보통 /user니 /user/1, /user/1/edit 이런식으로 만들어진다. 따라서 특정 확장자를 사용할 수 없다.

문제는 스프링이 이런 URL을 처리하게 하려면 웹 애플리케이션에 기본으로 등록된 다른 서블릿과 중복이 되지 않게 만들어줘야 한다. 보통 서블릿 컨테이너에는 스태틱 리소스(HTML, 자바 스크립트, CSS, 이미지 등)를 처리하는 디폴트 서블릿과 JSP를 처리하는 JSP 서블릿이 기본으로 등록되어있다. 디폴트 서블릿은 /에 매핑되어 있고 JSP는 확장자를 이용해서 *.jsp로 되어있다. 그리고 여기에 추가로 서블릿을 등록하면 URL 우선순위(매핑 조건이 긴게 우선)에 따라서 그 서블릿의 매핑에 해당하는 것은 등록된 것으로 가고 나머지는 디폴트 서블릿이나 JSP 서블릿이 담당한다. 스프링을 *.do와 같이 사용할 땐 그래서 문제가 없었다. 그런데 경로만 있는 URL로 가니 얘기가 달라졌다.

디폴트 서블릿을 안쓸 수는 없다. 따라서 스프링 서블릿(DispatcherServlet)을 /에 매핑할 수는 없다. 그러면 DispatcherServlet가 모든 스태틱 리소스까지 처리해줘야 한다. 그래서 보통 /app와 같은 서브폴더를 만들고 그 아래로 오는 요청을 스프링의 DispatcherServlet이 담당하게 만든다. DispatcherServlet의 매핑을 /app/나 /app/* 등으로 하고, URL은 /app/user, /app/user/1, /app/user/1/edit 이렇게 썼다.

그런데 app가 계속 붙으니 안이쁘다. 폼나게 RESTful하게 보이려면 도메인 이름 뒤에 바로 리소스 이름이 나오는게 좋다. 그냥 http://toby.epril.com/article/1 이런 식으로.

그래서 스프링 사용자들이 슬슬 사용하기 시작한게 UrlRewriteFilter다. 이 필터는 서버로 온 URL을 애플리케이션으로 넘길 때 강제로 변경해주는 역할을 한다.  UrlRewriteFilter은 서블릿의 매핑보다 세밀한 제어가 가능하기 때문에 원하는 방식으로 URL을 작성할 수가 있다. 일단 모든 스태틱 리소스는 /resource 등에 위치시킨다. 그리고 스프링 DispatcherServlet은 그냥 /app와 같은 서브 폴더에 매핑시킨다. 그런다음 UrlRewriteFilter를 적용한다.

스태틱 리소스인 /resource는 그냥 /resource로 그대로 가도록 한다. 대신 그 외의 /로 시작하는 경로는 앞에 /app를 붙이도록 만들어주는 것이다. 그러면 /resource로 시작하지 않는 모든 URL은 /app가 앞에 붙어서 넘어가므로 /app로 매핑을 해둔 DispatcherServlet처리하고 나머지는 그대로 URL이 유지되므로 디폴트 서블릿이 처리할 수 있는 것이다.

이렇게 해서 깔끔한 URL을 만들어 사용할 수 있긴한데, 제법 복잡한 UrlRewiteFilter를 공부해서 사용해야 한다는 번거로움이 있다. 그래서 책에도 UrlRewriteFilter를 사용하는 방법을 넣을까 하다가 독자들 머리만 더 아플까 해서 그냥 뺐다. 예제도 덜 이쁘지만 /app로 시작하는 URL을 그냥 사용하도록 했고. RESTful URL을 사용하는 ROO에서 사용한 UrlRewriteFilter를 보면 꽤나 복잡하다.

그런데 이런 불만이 나만 있던 것은 아니었나보다. UrlRewriteFilter를 쓰지 않고 스프링 DispatcherServlet을 /에 매핑해서 쓰면 안될까? 스프링에 안되는 게 어딨겠나. 결국 스프링 개발자들은 3.0.4에서 <mvc:default-servlet-handler/>를 추가해서 이 문제를 깔끔하게 해결해버렸다.

 

사용방법은 간단하다.

일단 DispatcherServlet을 그냥 /에 매핑한다. jsp와 같은 특정 확장자를 가진 URL말고는 모두 DispatcherServlet이 다 받는다. 일단 스프링의 기본 등록된 핸들러 매핑 전략을 이용해서 컨트롤러를 매핑해본다. @Controller가 담당하는 URL이라면 그리로 넘어갈거고. 그런데 그러다보면 /js/jquery.js 처럼 컨트롤러에 매핑안되는 URL이 나올 것이다. 이런 나머지 모든 URL은 <mvc:default-servlet-handler/>이 내부적으로 등록해주는 DefaultServletHttpRequestHandler이 담당한다. 이 핸들러(컨트롤러)는 /**로 매핑되어있다. 대신 핸들러 매핑 우선순위가 가장 낮다. 따라서 애노테이션 매핑 등등을 거쳐서 다 실패한 URL만 넘어온다. 그리고 DefaultServletHttpRequestHandler는 이 요청을 자신이 직접 스태틱 리소스를 읽어서 처리하는 것이 아니라, 원래 서버가 제공하는 디폴트 서블릿으로 넘겨버린다. 그러면 서버의 기본 디폴트 서블릿이 동작해서 스태틱리소스를 처리해버리는 것이다. 일단 스프링이 다 받고 스프링이 처리 못하는 건 다시 서버의 디폴트 서블릿으로 넘긴다는 아이디어이다. 멋지지 않은가?

그런데 사실 아이디어는 간단하지만 구현은 쉽지 않다. 디폴트 서블릿을 찾아서 사용하는 건 일반적인 접근방법이 아니다. 서블릿 스펙 2.0 부터는 하나의 서블릿이 다른 서블릿을 직접 찾아서 실행할 수 있는 방법을 막아버렸다. 그래서 ServletContext의 getServlets() 나 getServletNames()와 같은 메소드는 무조건 null을 리턴하도록 스펙에 명시되어있다. 대신 스프링은 URL 대신 이름을 이용해서 RequestDispatcher를 가져오는 getNamedDispatcher() 메소드를 이용한다. 물론 디폴트 서블릿 이름을 알고 있어야 하는데, 그건 스프링 개발자들이 주요 서버의 디폴트 서블릿 이름을 다 조사해놨다. 톰캣, 제티, JBoss, 글래스 피시는 이름이 default, Resin은 resin-file, WebLogic은 FileServlet, WebSphere는 SimpleFileServlet이다. 이 서버들의 디폴트 서블릿 이름은 자동으로 찾아준다. 그 외의 서버라면 디폴트 서블릿 이름을 직접 주면 된다. 보통 서버의 설정 폴더에 보면 디폴트 web.xml이 다 나와있다. 그걸 열어보면 디폴트 서블릿 이름을 알 수 있다. 톰캣이라면 conf 밑의 web.xml에서 찾을 수 있다.

톰캣 6에 보면 디폴트 서블릿이 다음과 같이 등록되어있다.

<servlet>
    <servlet-name>default</servlet-name>
    <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
     …
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

 

이제 3.0.4를 사용하면 특별한 이유가 아니라면 UrlRewriteFilter를 사용할 필요가 없다. 혹시 스태틱 리소스의 경로를 다이나믹하게(버전 폴더를 바꾼다거나) 바꾸는 필요가 있다면, 그때는 3.0.4에 함께 추가된 <mvc:resource>를 사용하면 된다. 그건 다음 시간에.

참. GAE에서는 이 기능을 사용할 수 없다. 구글이 수정한 GAE의 Jetty 소스를 보면 이 getNamedDispatcher()가 항상 null을 리턴하도록 해놨다. 리소스 접근에 제약을 걸어야 하기 때문에 코드를 통해서 디폴트 서블릿에 접근하는 것을 원천적으로 차단한 것이다.

점점 지겨워지긴 하지만 마무리는 해야 하니까. 처음 이 글을 쓰기 시작했을 때 생각처럼 어떤 시간이었든 책을 써왔던 지난 시간을 한번 정리하고 나서 다 잊어야지. 차마 글로는 옮길 수 없는 유쾌하지 못했던 기억들이 더 많았던 지난 2년여간의 시간들. 어쨌든 정리는 하고 넘어가야 하니까.

 

한국에서 돌아온 뒤 거의 하루 15시간 이상 책을 쓰는 데 매달렸다. 일단 흐름을 타고 나니 1부를 마무리 하는 것은 쉬웠다. 스프링 핵심기술 소개는 6장에서 마무리했지만 거기서 만족할 수 없었다. 단지 스프링이 이렇게 OO와 DI를 비롯한 핵심가치를 자신에게 적용했다는 것을 이해하는데 만족하지 말고 그것이 스프링 사용자 자신의 코드에도 그대로 적용될 수 있기를 바랬다. 그래서 7장을 썼다. 내용은 엉성할지 모르겠지만 7장은 내가 이 책에서 가장 아끼는 장이다. 책을 통해서 내가 가장 하고 싶었던 이야기이기도 하고. 그리고 1부의 마무리로 처음 써놨던, 버리려고 했던 1장을 넣기로 했다. 물론 거의 새로 쓴 것이긴 하지만. 원래 가장 먼저 얘기하려고 했던 도대체 스프링이란 무엇인가라는 질문과 그에 대한 내 생각을 간략하게 정리했다. 1부 끝. 한국을 다녀와서 며칠 지나지 않아 1부를 마쳤다.

그리고 스프링의 기술을 주제별로 설명하는 2부 시작. 2부는 1부보다 훨씬 쉬울 것이라고 생각했다. 그저 스프링의 기술을 쭉 나열해가며 사용방법을 설명하고 평소에 생각해뒀던 선택 기준에 관한 내 의견을 넣으면 될 테니까. IoC/DI를 다루는 10장에서 이미 600페이지가 훌쩍 넘었다. 800페이지가 목표니까 이제 얼마 안남았다고 생각했다. 미리 준비해뒀던 학습 테스트 코드도 많은 도움이 됐다. 그리고 스프링 3.0도 RC버전이 출시되고 최종 릴리스가 눈 앞에 보였다.

이제 끝인가 보다 생각하면서 12월이 시작됐다. 그리고 처음으로 용기를 내서 김희정 부사장님께 먼저 연락을 했다. 늦어도 12월 말까지는 초고를 드릴 수 있을 것 같다고 말씀드렸다. 스프링은 예상과 달리 계속 지연되서 12월 중순에나 나오게 됐고 약속대로 스프링 출시에 맞춰서 책이 나올 수 있을 것 같다고 얘기했다. 물론 스프링이 늦게 나올 것이란 건 충분히 예측했던 일이었으니 다르긴 뭐가 달라. –_-; 죄송하니까 말이라도 그렇게 했어야지.

아내도 11월 말에 학기를 마쳤고 집안일을 전담할 수 있게 됐다. 나는 그저 12월 무더위와 싸우면서 미친듯이 마무리 해나가면 될 것 같았다. 하지만 예상치 못했던 일이 생겼다. 아내가 임신을 한 것이다.

결혼 후 거의 7년만에 평화를 가질 때는 병원의 도움을 받아야 했다. 쉽게 아이가 생기는 체질이 아니라고 했다. 아내는 계속 둘째를 원했다. 혼자는 외로우니까 친구처럼 지낼 형제가 있어야 한다고. 나도 둘째가 있으면 좋겠다고 생각은 했다. 하지만 쉽게 생길 것이라고 기대를 하지는 않았다. 아마 또 병원에 다녀야 하지 않을까 싶었다. 그런데 어느날 갑자기 둘째가 생겼다.

병원에 가보니 5주라고 했다. 한편으로 기뻤지만 다른 한편으로는 걱정이 시작됐다. 평화를 가졌을 때 지독하게 심한 입덧을 했던 것이 기억났다. 입덧이 없거나 가볍게 지나는 사람도 있지만 지독하게 심한 입덧을 경험하는 사람도 있다. 오죽 심하면 출산 때의 고통 때문이 아니라 입덧 때문에 아이를 가지는 것이 두렵다는 얘기를 할 정도다. 아내가 딱 그랬다.

입덧이 서서히 심해지면서 중병을 앓는 사람처럼 누워있어야만 있어야 했다. 물 조차도 마시기 힘들어 했다. 겨우 물 한모금을 마셔놓고 그보다 훨씬 더 많이 토하기도 했다. 평화를 가졌을 때 입덧하면서 자주 먹었던 누릉지를 만들어서 끓여주었지만 그것도 거의 입에 대기 힘들어했다. 평화 때보다 훨씬 빨리 입덧이 시작됐고 훨씬 더 심하게, 오래 진행됐다. 원래 둘째는 입덧이 덜하다는 얘기도 있는데 다 뻥이다. 평화 때처럼 친정에 가있을 수도 없었다. 그렇다고 누군가 와서 도와줄 사람도 없었다. 하루 종일 침대에 누워서 괴로워하다가 물 몇 모금, 묽게 만든 누릉지 조금 먹고 그리고 수시로 토하고. 냄새 때문에 방 밖으로 나오기도 힘들었다. 평화랑 놀아주는 것도 물론 불가능했다. 갑자기 모든 집안 일과 평화를 돌보는 것이 내 책임이 됐다. 겨우 짬을 내서 회사 일에 시간을 쓰고 나면 원고를 쓸 시간이 없었다.

아침에 일어나면 평화를 어린이집에 보낼 준비부터 해야 했다. 평화 점심 도시락을 만들고 간식과 준비물을 챙기고 평화를 깨워서 씻기고 아침을 먹이고 어린이집에 데려다 주고 왔다. 돌아오면 집안 청소와 설거지, 세탁을 하고 아내 상태에 따라서 먹을 음식을 준비해야 했다. 평화를 가졌을 때는 다른 음식에는 전혀 손을 대지 못했지만 누릉지 끓인 것은 겨우 겨우 먹었던 기억이 났다. 한국에서처럼 누릉지를 쉽게 구할 수 없으니 내가 직접 만들어야 했다. 밥을 후라이팬에 얇게 깔고 가장 약한 불에 1-2시간 두면 그럴싸한 누릉지가 만들어진다. 입덧이 심하면 맹물도 제대로 못삼킨다. 억지로 마셨다가 토하면 오히려 수분이 더 빠져나가서 좋지 않다. 그래서 누릉지를 끓어서 먹이려고 노력했다. 그것도 며칠 가지 못했다. 아예 하루 종일 물 몇 모금 말고는 아무것도 먹지 못하기 시작했다.

도저히 안되겠다 싶어서 병원에 가봤다. 의사는 상태가 안좋다고 구토억제제를 처방해줬다. 하지만 약을 먹어도 별 효과가 없었다. 입덧을 시작하고 입덧 시작하고 2주가 지났을때 몸무게가 5킬로나 빠져있었다. 동네 병원에서 검사를 해보더니 상태가 많이 안좋다고, 그대로 있으면 엄마도 태아도 위험하니 얼른 종합병원 응급실로 가라고 했다. 응급실 의사는 입원을 해야 할 수도 있다고 했다. 그나마 응급실에서 구토억제제 주사와 수액 두 팩을 맞고 나니 겨우 혈색이 돌아왔다. 수분이 공급되면서 상태가 호전되니 입원은 하지 않아도 괜찮겠다고 했다. 대신 보통 구토억제제로는 안될 것 같고 말기 암 환자나 수술한 환자들이 먹는 쎈 구토억제제를 먹으라고 했다. 그나마 그 약을 먹으면 잠시라도 역겨운 것이 덜해서 물이라도 조금씩 마실 수 있게 됐다.

평화도 당황했다. 항상 자기랑 놀아주고 안아주던 엄마가 하루 종일 침대에 누워있기만 한데다 엄마 곁에 가지 못하게 내가 자꾸 떼어 놓으니 속상했을 것이다. 나도 종일 집안일을 하거나 틈틈이 원고 몇 줄이라도 써야 했기에 평화랑 놀아줄 시간이 별로 없었다. 낮에는 어린이집에 보내고 돌아오면 좋아하는 비디오를 틀어주고 앉혀놓는 수밖에. 어린이집에 안가는 날은 하루 종일 비디오와 TV만 봤다. TV가 지겨워지면 나에게 와서 놀아달라고 칭얼거리며 손을 잡아 끌었다. 잠시 놀아주다가 괜찮은 것 같아 자리에 돌아와 원고를 좀 더 쓰고 있으면 어느새 다시 달려와서 나를 잡아 끌었다. 낮잠은 물론이고 밤에도 내가 평화를 재워야 했다. 운이 좋으면 같이 누워서 30분만에 잠들기도 하지만 보통 잠이 들려면 1-2시간은 걸렸다. 잠이 든 걸 확인하고 나와서 다시 아내를 돌보거나 집안일을 해야 했다.

집안일이라는게 정말 끝이 없었다. 아내는 본격적으로 구토억제제를 먹기 시작하면서 그나마 속에서 받아주는 시원한 수박이나 오렌지같은 과일 그리고 패들팝아라는 아이스크림을 계속 원했다. 매일 장을 봐와야 했다. 일주일에 3일은 평화를 어린이집에 보냈는데 그런 날은 좀 더 시간을 벌 수 있을 것 같지만 막상 도시락을 준비하고 짐을 챙겨 데려다 주고 데리고 오고 하는 시간을 고려해보면 어린이집에 가지 않는 날에 비해서 겨우 3-4시간 정도 시간을 벌 뿐이다. 아내 먹을 것을 준비하고 집안일을 하다보면 다시 평화를 데려와야 할 시간이 되는 경우도 흔했다.

막막했다. 도저히 책을 쓸 수 있는 시간이 없었다. 그나마 어린이집에 평화를 보내고 아내 필요한 것을 챙겨준 뒤에 잠깐, 그리고 평화를 재운 뒤에 늦은 밤 중에 잠깐. 그게 내가 낼 수 있는 시간의 전부였다. 운이 좋은 날은 4-5시간 어떤 날은 2-3시간씩 밖에 쓸 수 없었다. 고객사의 요구가 들어오면 한밤중에라도 일을 해야 했다. 2010년 계약을 다시 하기 위해서 분석자료를 준비하고 제안서를 쓰는 시간도 필요했다.

12월 말까지 원고를 마무리하겠다고 큰 소리쳐놨는데 12월 한달 내내 그나마 쓰던 장도 마무리를 할 수 없었다. 원래 계획은 12월 말에 초고를 넘기고 1월에는 마음 편하게 휴가를 떠나는 것이었다. 12월부터 1월은 호주의 최대 휴가철이다. 그때가 가장 더운 여름이니까. 하지만 계획은 다 무산됐다. 크리스마스고 연말연시고 그런 것도 없었다. 매일 매일 끝이 보이지 않는 막막함 뿐이었다. 아내는 끝도 없이 계속 되는 심한 입덧으로 매일 힘겨워 했고, 나는 다시 끝이 보이지 않는 책의 마무리에 괴로워 했다.

지금은 이렇게 담담히 글로 적지만 그때는 정말 견디기 힘들만큼 괴로웠다. 내 인생에서 그렇게 힘든 시간은 처음이었다. 도무지 끝날 것 같지 않은 막막함이 들 땐 그 상황을 벗어나는 길은 죽음 뿐이라는 생각도 들었다. 한 자도 못쓰고 종일 뛰어다니다가 걱정 속에서 잠이 들때도 많았다. 고통스러워 하는 아내를 보면서, 뭔가 변한 엄마 아빠 모습에 스트레스를 받는 평화를 보면서도 내가 아무 것도 해줄 수 있는 게 없다는 사실이 괴로웠다. 여유를 가지고 집중하기 힘들었지만 그래도 죽을 힘을 다해서 빨리 마무리 하려고 노력했다. 겨우 겨우 1월 말에 11장을 끝냈다. 처음 생각대로라면 12월에 한 주면 다 썼을 것인데 무려 두달이나 걸렸다. 12월 말에는 초고를 넘긴다고 큰 소리 처놨는데 또 연락이 없으니 김 부사장님은 얼마나 더 실망했을까하는 걱정도 들었다.

그런데 11장을 끝낼 즈음에 내가 큰 착각을 하고 있다는 것을 깨달았다. 약속한 페이지를 맞추기 위해너 나름 재밌고 깊이 있는 내용은 다 빼고 꼭 필요하다고 생각되는 중요한 내용만 고르고 골라서 넣었는데도 11장을 끝냈을 때 이미 페이지가 750이었다. 아직 2부에서 가장 중요하다고 생각하는  MVC/@MVC와 Aspect/AOP, Test 기타 기술 등등이 남았는데 남은 페이지는 겨우 50. 그동안 계속 800을 채우면 끝이다라고 생각하면서 썼는데, 사실은 분량조절을 잘못해왔다는 것을 그제야 깨달았다. 스프링 기술의 선택가능한 옵션을 빠짐없이 소개하고 간단한 선택 가이드를 제공해 주면 되는 2부도 생각보다 쓸게 많다는 것을 그제야 깨달았다.

이미 여러번 800페이지 정도만 쓰겠다고 장담을 했는데 이제와서 분량을 더 늘리겠다고 할 수도 없었다. 그렇다고 이미 써논 것을 다시 편집해서 내용을 줄이자니 그것도 막막했다. 처음부터 끝까지 하나의 코드가 계속 연결되는 1부는 어떻게 건드릴 자신이 없었다. 그래서 일단 그냥 되는데까지 쓰기로 작정했다. 책을 다 쓰고 800페이지를 넘어가는 내용은 빼서 PDF로 공개하든지 그냥 버리든지 할 생각이었다. 아깝지만 그나마 생략해도 어색해보이지는 않는 7장과 8장은 빼버릴까도 생각했다. 적절하게 주제별로 비율을 따져보고 미리 페이지 분배를 꼼꼼하게 하지 않고 써논 것이 잘못이었다.

한숨이 나왔지만 어쩌겠는가 계속 써야지. 그렇다고 MVC/@MVC를 대충 쓸 마음은 전혀 없었다. 그리고 여전히 칭얼대는 평화와 입덧하는 아내를 돌보며 집안일에 매달려야 했지만 마지막이라고 생각하고 죽을 힘을 다해서 12장,13장을 써내려갔다. 그리고 단 20일만에 당시 편집하던 워드 파일로 210페이지(실제 책에서는 270페이쯤 되는 것 같다)에 달하는 MVC/@MVC를 다 써버렸다. 테스트 코드는 이전보다 더 많이 만들었고. 초기에 학습 테스트를 만들 때는 웹 기술의 테스트를 만드는 것이 너무 어려워서 생략을 했다. 그래서 12장을 쓰면서야 겨우 MVC 테스트를 하기 위한 간단한 지원 도구를 만들었다. 그리고 방대한 스프링MVC 내용을 하나씩 다 테스트 해가면서 넣었다. 기존 MVC에 비해 기능은 방대하고 내부 동작 방식도 복잡한 @MVC는 문서가 너무 빈약했다. 레퍼런스나 API문서만 가지고는 보이지 않는 프레임워크 내에서 일어나는 일과 규칙을 다 파악할 수 없었다. 그래서 스프링 @MVC 소스 코드를 모두 분석해야만 했다. 그렇게 분석한 내용을 가지고 가정을 세우고 그것을 2-3중의 테스트로 검증하고난 뒤에야 겨우 그 내용을 추가하는 식으로 써 나갔다. 문서와 소스를 분석하고 테스트를 만들어 검증하는 시간을 빼면 거의 하루에 20페이지씩 쓴 것 같다. 지금 다시 돌아봐도 어떻게 그 여유도 없는 상황에서 그 많은 내용을 다 썼는지 상상이 되지 않는다. 더 이상은 물러날 곳이 없다는 절박함 때문에 초인적인 힘이 났던 것일까.

그리고 14,15,16장을 열흘만에 다 써버렸다.  그렇게 해서 3월 4일 초고를 끝냈다.

마지막 장의 정리 절을 쓰고 나니 1000페이지가 조금 넘었다. 저장 버튼을 누르는 데 눈물이 났다. 지난 2년 넘는 시간동안, 특별히 지난 3개월의 끔찍했던 시간이 떠오르면서 이제야 살았다는 생각이 들었다. 아직 원고를 리뷰하고 교정하는 시간이 남았지만, 그래도 일단 마무리 했다는 것에 안도할 수 있었다. 정말 기분이 좋았다. 그 뒤로 리뷰를 마치고 초고를 넘겼을 때, 출판사 편집을 거쳐서 최종 원고 수정을 마쳤을 때, 책이 인쇄되서 나왔다는 얘기를 들었을 때, 그리고 책을 받았을 때도 기쁘긴 했지만 처음 원고를 마쳤던 그날만큼은 아니었다.

 

출판사에서 특급우편으로 보내준 내 책이 며칠전에야 도착했다. 책을 받아서 가장 먼저 아내에게 건내주었다. 나랑 함께 그 힘든 시기를 보내왔던, 답답하게 오랜시간 책을 쓰고 있는 남편을 보면서 한번도 잔소리도 한 적이 없는 착한 아내. 책을 살펴보라고 건네주고 잠시 방에 들어왔다 다시 나와보니 아내가 울고 있었다. 힘들었던 그때가 생각나서, 그래서 더 감격스러워서 우는 것이라고. 아내도 그때 참 많이 힘들었던 것 같다.

 

지금까지 별 시덥지 않은 얘기와 투덜거림으로 긴 글을 써온 것은 사실 오늘 이 얘기를 적고 싶어서였다. 그때는 이런 글을 쓸 수가 없었다. 책을 마무리 하지 못한 나는 죄인이었다. 맘 편하게 내가 즐기고 싶은 기술을 살펴보는 것도 용납하기 힘들었고, 내가 다 잘못해서 책을 완료하지 못한 주제에 힘든다는 말을 하는 것도 비겁해 보였다. 그래서 힘들어도 힘들다고 내놓고 말을 할 수가 없었다.

하지만 이제는 괜찮겠지. 다 지났으니까. 긴장했던 시간들, 짜증났던 시간들, 가끔 재미와 행복을 느꼈던 시간들, 그리고 견디기 힘들만큼 힘들었던 시간들.. 그 과정을 거쳐야 책이 하나 탄생하는 것인가. 나만 그런거겠지.

2010년 1월 1일. 새해 첫날이었지만 별 다른 것은 없었다. 여전히 괴로워 하며 끙끙 앓는 아내와 바뀐 환경에서 힘들어하던 평화, 그리고 잠시라도 짬이 나면 크리스마스든 새해 첫날이든 상관없이 자리에 앉아서 DI가 어떻고 @Inject가 어떻고 하는 얘기를 써나가야 했던 나. 그냥 달력을 보면서 2010년인가보다, 여전히 책을 끝내지 못한 책로 2010년을 맞았구나 하는 생각을 했다.

그리고 일년에 겨우 한 두 번쓰는 일기를 썼다. 차마 블로그나 공개된 곳에는 쓸 수 없었던 나 혼자만의 이야기를 가끔 적는다. 거기에 2010년 새해 목표를 적었다. 살아남기. 올해목표는 일단 성공한 듯. 그 일부를 여기다 옮겨본다. 이제는 얘기해도 되니까.

—————————–

1 Jan 2010

힘겹게 시작한 2010년. 새해가 시작한다는 느낌도 없다. 아니 느낄 조그마한 여유도 없다. 입덧하는 은성. 거의 폐인이나 다름없이 온종일 누워서 앓기만 한다. 엄마의 변화 때문에 힘겨워하는 평화. 전에 안하던 짓들을 슬슬 한다. 손에 잡히지 않는 일. 시간도 돈도 여유가 없는데 왜 이렇게 몸이 더딜까. 그나마 는 것은 집안 일 실력 뿐.

평화가 말을 듣지 않는 것 때문에 미친 듯이 흥분하는 내 모습을 보면서 아빠로서 기본적인 자격도 없는 것이 아닐까 하는 괴로움.

막막함.

그래도 절망하거나 힘겨워 하지 않고, 그래도 하루 하루 산다. 오늘 못하면 내일 하고, 오늘 조금 잘못했으면 내일 조금 덜 잘못하려고 하고, 그렇게 포기하지 않고 산다. 이제 내 목표는 어떤 멋진 꿈이 아니라, 포기하지 않고 살아남는 것. 이 삶을 살아 내는 것이다. 살아남자.

휴. 힘을 내자.

아자 아자.

내가 잘하는 한가지.

포기하지 않는 것.

지저분하게라도, 서글프게라도, 꿋꿋하게 사는 것.

2010. 시작이다.

책을 쓰는 동안 가장 힘든 것이 무엇이었냐고 누가 물어온다면 수많은 일들이 머리에 떠오르겠지만, 그 중에서 가장 대표적인 두 가지만를 꼽자면 내가 쓰려고 하는 내용이 공격 받는 것을 발견하는 것과 끊임없이 발생하는 호기심을 억눌러야 하는 것 두가지를 들고 싶다.

책이 나오고 책의 내용이 공격 받는 것은 차라리 나을 것 같다. 이미 출간되서 독자 손에 들어갔으니 뭐 어쩌겠는가. 자기들끼리 지지든 볶든 상관할 바도 아니고, 상관해봤자 온라인으로 출판된 글과 달리 인쇄된 책의 내용을 고칠 수도 없으니 차라리 마음이 편할지도 모르겠다는 생각을 했다. 물론 속은 많이 상하겠지만.

사실 책의 내용에 대한 공격은 원고가 내 손을 떠나기 전에 이미 시작된다. 책을 쓰는 내내 저자 머리 속에서 치열한 전쟁이 벌어지기 때문이다. 내가 쓴 글을 다시 읽을 때마다 과연 이 얘기가 정말 맞는 것일까 혹은 잘못 설명한 것은 아닐까 하는 의심이 끊임없이 들었다. 책을 쓰기 전에는 분명한 확신을 가지고 어디서든 당당하게 얘기했던 내용조차도 책의 원고에 넣고 나면 갑자기 수상하게 보였다. 그래서 관련된 책을 찾아보고 인터넷을 뒤지면서 내가 설명하는 내용이 타당한지 검토하고 또 검토했다. 물론 논쟁거리에 속하는 그런 주제는 어쩔 수 없다. 그건 내가 어느 한편을 지지하든지 아니면 적절한 선에서 양다리를 걸치든지 하는 수밖에. 대신 독자들이 최종 판단을 내릴 수 있도록 충분한 근거들을 나열해주는데 신경을 썼다. 때로는 한 문단의 내용을 뒷받침 해주는 근거를 뽑아내기 위해 책 한권을 통채로 읽은 적도 있다.

내 스스로 확신이 없는 않는 내용은 책에 넣지 말자는 생각이었다. 물론 내 확신이 틀린 수도 있지만 그거야 어쩔 수 없고.  그동안 다른 책을 읽으면서 잘못된 주장이나 왜곡된 사실이 얼마나 많이 책에 들어가는지 놀랄 때가 많았다. 저자가 지지하는 기술을 위해서 경쟁관계에 있는 기술을 폄하하는 모습을 보면 짜증도 났다. 특히 스프링은 그런 공격을 가장 많이 받은 기술이다. 희한하게도 스프링은 사람들의 심기를 건드리는 뭔가가 있는 듯 하다. 자신이 지지하는 개발철학이나 기술을 절대적으로 신봉하는 사람은 그래서 스프링이 불편하다. 물론 나중에 스프링이 대세다 싶으면 자신이 비난했던 일은 쏙 감추고 스프링 전문가  행세를 하고 다니기도 하지만.

저자의 성의가 부족해서 잘못된 사실이나 설명을 책에 남기는 것은 어떻게든 피하고 싶었다. 그래서 스프링 기술에 대한 설명은 문서만 참고해서 작성하지 않고 일일이 학습테스트를 만들어서 내 눈으로 동작하는 것을 직접 확인하려고 노력했다. 2부 예제인 Part2 프로젝트의 학습 테스트 코드는 그렇게 만들었던 테스트의 일부를 독자들도 참고해보라고 넣은 것이다.

문제는 1부였다. 코드야 거의 TDD에 준하는 테스트를 계속 작성해가면서 만들었으니 기능적으로는 문제가 없을 것이다. 하지만 스프링의 프로그래밍 모델과 개발철학을 이해하는데 도움이 될 것이라고 생각해서 동원했던 다양한 이론과 원칙, 패턴들에 대해서는  간단히 검증할 수 있는 것이 아니라서 고민을 많이 했다. 처음엔 애자일 개발 이론을 동원해서 스프링의 특징을 설명하려고도 노력했는데, 애자일은 너무 방대하고 내가 도저히 감당할 수 있는 주제가 아니라고 판단되서 그 내용은 모두 제거했다. 대신 가장 단순하고 명확한 한 가지 이론을 꺼내서 그것에 대한 이론적인 설명대신 그 이론이 코드에 적용되서 코드가 발전하는 모습을 보여주려고 노력했다. 이론이 눈에 보이는 코드에 적용되서 더 나은 코드가 되는 모습을 보여주고 싶었다. 반대로 그런 코드의 개선 이유를 설명할 수 있는 용어와 이론을 알려주고 싶었다. 그리고 그렇게 개선된 코드가 바로 스프링의 핵심 기술이고 스프링이 개발자들에게 권장하는 코드라는 것을 보여주기 바랬다. 그래서 선정한 가장 간단하고 명료한 개발 이론이 바로 관심사의 분리(SoC)였다. SoC도 깊이 들어가면 복잡하고 방대한 주제긴 하지만, 그냥 그 용어의 표면적인 의미만 가지고도 충분히 내가 원하는 설명을 이끌어낼 수 있을 것이라고 기대했다. OO원칙이니 패턴이니 하는 얘기를 너무 자주 들먹이면서 설명을 하면, 그런 이론을 좋아하는 사람들은 만족할지 모르겠지만 그렇지 않은 개발자들은 오히려 피로를 느낄 수 있기 때문이었다. 그래서 가장 단순한 "관심이 다른 코드는 분리하는 것이 좋다"는 명제 하나를 가지고 코드를 살펴보는 것으로 스프링의 모든 개발철학과 핵심기술을 설명하려고 시도했다.

스프링의 DI는 기본적으로 SoC를 바탕으로 한다. DI는 의존관계에 대한 것인데, 의존관계가 성립하려면 적어도 두 개의 구분된 존재(오브젝트)가 필요하다. 그래야 한 쪽이 다른 한 쪽을 의존할 수 있고, 그래야 DI도 성립하니까. 그래서 DI의 기본 전제는 분리다. 사람들이 스프링을 왜 제대로 사용하지 못할까를 고민하면서 내가 내린 결론은 겨우 3계층으로 구분하고 나면 더 이상 분리를 할 줄 모르기 때문에, DI할 필요를 찾지 못하기 때문이라는 것이다. 성격이 다른 코드를 하나의 클래스와 메소드에 마구 우겨 넣어놓았으니 무슨 DI가 가능하겠나. 가장 원시적인 DI가 적용된 템플릿/콜백도 의미있는 분리가 기본 전제다. 그렇게 따져보면 스프링의 모든 기술은 다 적절한 관심사(책임, 변경조건, 성격.. 뭐라고 해도 좋다)에 따라 코드를 분리하는 데서 시작된다. SoC라는 용어가 소프트웨어 개발의 가장 근간이 되는 기본적인 원칙으로 자리를 잡게 된 것도 비슷한 맥락이라고 봤다.

내 책을 본 사람들은 알겠지만 1장의 앞부분에서부터 이 SoC가 등장한다. 사실 SoC라는 용어가 중요한 것은 아니니 그 뒤로는 그냥 "관심(책임, 변하는 성격)이 다른 것이 같이 있네? 분리해 보고 어떻게 되나 살펴보자"라는 식의 설명으로 바꾸긴 했지만, 이 원칙을 1부 내내, 7장까지 끊임없이 반복해서 적용한다. 그러면 스프링 다운 코드가 되고 스프링 자신이 된다. 짜잔. 이제 1부의 내용이다. 거창한 객체지향이니 원칙, 패턴 같은 것도 따져보면 여기서 부터 출발하는 것이라고 생각했고, 그런 패턴의 기계적인 적용에 앞서서 먼저 적절하게 분리되야 할 코드를 살피는 것(물론 응집도를 높이기 위해서 분리한 것을 다시 유연한 방식으로 결합하는 주제도 나오지만)에만 충실해도 도움이 될 것이라고 생각했다.

그리고 1부의 마지막인 8장에서는 스프링이 이 적절한 분리(SoC)를 통해서 엔터프라이즈 개발의 복잡함을 효과적으로 다룰 수 있게 해준다는 결론을 내렸다.

그런데 어느날 우연히 "SoC가 가져오는 복잡성을 극복하는 방법"이라는 글을 봤다. 글의 취지나 내용은 대충 이해하지만 이 제목과 SoC, 복잡함이라는 단어를 사용하는 방식에는 동의할 수 없었다. 그런 자극적인 문구를 보니 갑자기 내가 썼던 글들이 온통 부정당하는 느낌이 들었다. 지금까지 SoC가 어떻게 복잡함을 극복하는지에 대한 이야기를 풀어나가고 있었는데 SoC가 복잡성을 가져온다니! 그 글에선 SoC라는 단어를 극히 협소하고 제한된 의미로 사용하고 있다고 생각됐다. 게다가 복잡함에 대한 설명도 받아들이기 힘들었다. 글의 취지는 이해하지만 그래도 마음이 불편하고 신경 쓰였다.

그래서 블로그에 가볍게 반박하는 글을 썼다. 글 전체에 대한 반박이라기 보다는 복잡함과 SoC라는 단어 사용에 대한 반론이었다. 글을 썼던 S님도 내 블로그를 찾아와 "의견 고맙다"는 답글도 달아줬다.

나오지도 않은 책의 내용을 반박당하는 듯해서 찝찝했던 기분은 다시 좋아졌고 다시 내 주장을 계속 펼쳐나가면 되겠다고 생각했다. 그런데 그 때 사고가 터졌다. 블로그계의 악동 영회였다. SoC에 관한 글에서 복잡함이라는 주제에 대한 내용은 내가 충분히 반박할 수 있다고 생각했지만, 글의 결론으로 나오는 UML모델링 툴의 사용이 해결책이다라는 내용은 내가 그 툴을 거의 써본 적이 없고 모델링 툴을 통한 접근방법에 대해서는 별 관심도 없었기에 내가 다룰 내용이 아니라고 생각했다. 대신 평소에 모델링툴 만능주의자들을 끊임없이 비난해왔던 CBD 모델링 컨설턴트 출신의 영회가 생각났다. 게다가 언급된 툴은 마침 영회가 잘 안다고 하던, 그래서 블로그에 소개도 자주 하던 것이었다. 그래서 마침 메신저에 들어온 영회에게 그 글을 보여주면서 의견을 물었다. 영회도 그 내용이 불만이었다. 그래서 자기도 글을 하나 쓰겠다고 했다.

그런데 웬걸 다음날 아침에 난리가 났다. 영회가 또 사고를 쳤다는 얘기가 들려왔다. 영회 블로그를 급히 가보니 S님의 글을 링크해놓고 "아직 경험이 없고 어려서 뭘 모른다"거나 "닷넷 개발자들은 수준이 낮다"는 식의 자극적인 얘기가 적혀있었다. 모델링 툴에 대한 그 글의 해법에 대해서 의견을 써보라고 했더니 그런 얘기는 없고 인신공격으로 보일 수 있는 글을 적어놨다.

그때문에 한동안 시끄러웠다. 사실 영회 글의 파급력이 엄청났기 때문에 내 글은 묻혔다. 게다가 S님은 내가 영회랑 짜고 자기를 공격했다는 식으로 나를 비난하기 시작했다. 억울했다. 해명을 하려고 메신저로 연결해서 이야기를 나눴지만, 영회의 공격에 감정이 많이 상한터라 반응이 안좋았다. 공격의 화살은 오히려 내게로 돌아왔다. 내가 영회한테 시켜서 그런 글을 쓰게했다는 식의 얘기가 떠돌았다. 영회가 그렇게 오해하기 딱 좋은 댓글("형이 시켰자나")을 써놨기 때문이다. 영회한테 글을 알려주고 글을 써보라고 했지만 그게 자신의 평소 주장을 이용해서 글의 내용을 반박을 하라는 거였지, 닷넷 개발자를 깔아뭉개거나 엄마젖 더 먹고와라는 식의 글을 쓰라는 것은 아니었는데 내가 그런 악의적인 글을 쓰도록 뒤에서 조종한 사람 취급하는게 억울했다.

영회도 막상 일이 커지니 당황해서 글을 수정하고 지우고 자극적인 문구에 대해 사과하는 등 수습하느라 바빴다.

피곤한 경험이었다. 물론 나중에 S님을 잘 달래서 오해는 풀어줬고 좋은 사이가 될 수 있었지만 서로에게 조금씩 상처를 남긴 유쾌하지 않은 기억이다. S님 기분을 풀어주기 위해서 N모씨가 쓴 영회에 대한 인신공격/비방 글을 모두 찾아서 보여주기도 했다. 그리고 인터넷에 글을 남기고 활동하는 것은 언제든 이런 공격을 받을 수 있다는 것, 그리고 그런 위험을 감수할 수 밖에 없다는 것에 대해서 설명했다. 나도 "xxx에 경험도 없는 놈이~"라는 식의 인신공격을 받아본 적이 있기 때문에 그 심정을 대충 이해한다. 인신공격을 이용해서 자기 주장을 내세우는 것은 치사하지만 상당히 효과적이다. 그래서 더 나쁘다. 상대방의 발언 내용에 대해서 논리를 가지고 반박하는게 아니라, "너는 경력이 얼마 안되자나. 그러니까 네 주장은 틀렸다"는 식으로 몰고가는 것이다.

책의 내용이 공격받는 듯한 느낌이 들어서 시작하긴 했지만 순수하게 글의 내용만 가지고 토론했다면 감정 상하지 않고 적절하게 마무리할 수 있는 일이었는데 하는 아쉬움이 남는다. 스프링 포럼에서 기술적인 토론이 벌어지면 상당히 강한 공격과 반박이 오고 간다. 하지만 그 토론의 내용는 모두 객관적이고 기술적인 것이고, 개인적인 공격이나 그런 공격을 이용한 치사한 주장 같은 것은 찾아보기 힘들다. 그래서 격렬한 토론이 오고 간 뒤에도 기분 좋게 끝낼 수 있고, 또 그러는 사이에 많은 것을 배울 수도 있다. 하지만 한번 인격을 공격하기 시작하고 그것을 자기 주장의 근거로 삼으려는 시도를 하고 나면 지저분해질 수 밖에 없다. 사실 그런 유혹은 항상 있고, 사적인 대화나 술자리에서는 그런 얘기가 쉽게 오고가기도 한다. 하지만 공개된 블로그 등에서 그런 얘기를 하는 것은 차원이 다르다. 누군가는 크게 기분을 상하고 의욕을 잃을 수도 있다. 영회만 그런 실수를 하는 것은 아니다. 세계적으로 유명한 개발자나 IT계 종사자들 사이에서도 그런 일이 종종 발생한다. 얼마전에는 유명 블로거인 조엘이 밥 마틴과 켄트 벡을 영회와 비슷한 방식으로 비꼬았던 일이 있었다. 나중에 공개적으로 자신의 그런 발언에 대해 사과를 하기는 했지만, 그러는 사이에 밥 마틴은 물론이고 평소엔 잘 흥분하지 않는 켄트 벡까지도 감정이 실린 글을 썼고 댓글을 통해서 심한 이야기들이 오고가는 것을 봐야 했다. 개빈 킹은 예전에 화가나면 문장이 F로 시작하는 글을 남기기도 했다. 그래서는 건전한 기술 토론이 이어질 수가 없다.

아무튼, 그런 일로 또 몇 날을 진도도 제대로 못나가고 신경만 잔뜩 쓰면서 보내야 했다. 좋지 않은 경험을 하고 나니, 그 뒤로 책의 내용과 관련된 글이나 스프링을 공격하는 글을 봐도 그냥 무시하고 넘어가거나 아니면 혼자서 투덜대고 말아야 했다.

어쨌든, 책을 쓰는 동안 저자의 머리 속에서는 보이지 않는 치열한 전쟁이 일어나는 것 같다.

 

두 번째는 책의 주제에만 장시간 집중해야 하니 다른 기술에 호기심이 일어나도 자제해야 했던 것이다. 나는 오랫동안 프로그래밍을 취미로 해왔다. 새로운 것을 좋아하고 무엇인가 창조적인 일을 하는 것에 관심이 많은 나에게 끊임없이 새로운 기술이 쏟아져 나오고 원하는 대로 만들고 실행하고 남들이 사용하는 것을 지켜볼 수 있는 프로그래밍은 최고의 취미였다. 우연한 기회에 아르바이트로 일을 시작했다가 현장에서 일을 해야지만 만질 수 있는 대형 시스템의 매력에 빠져서 아예 직업으로 선택하게 되었지만. 일을 하는 중에 어떤 일을 할지 선택할 수 있는 기회가 주어지면 나는 항상 내가 해보지 않은 새로운 기술과 언어, 환경, 도메인에 우선순위를 두었다. 끊임없이 내 호기심을 자극해줄 수 있는 일을 찾았다. 그래서 프로젝트를 마칠 때면 고객사로부터 특채로 뽑아줄테니 직원으로 들어와서 일을 하라는 제안을 받았지만, 한 회사에서 한 가지 시스템을 몇 년씩 만져야 하는 일은 정말 지루해 보여서 도저히 받아들일 수 없었다.

그런 내가 스프링, 그것도 스프링의 기초와 핵심 기술 몇 가지에 매달려서 연구하고, 그것을 이리 저리 풀어서 설명하는 책을 쓰는 일에만 2년 가까이 집중해야 했던 것은 정말이지 고문이었다. 물론 책을 쓰면서 시간을 따로 떼서 다른 기술을 공부할 수도 있었지만, 계속 해서 밀리는 일정과 그에 따른 부담이 커지면서 책의 내용 외에 관심을 두는 것은 왠지 외도하는 느낌이 드는 데다 출판사에 미안한 마음 때문에라도 자제할 수 밖에 없었다. 블로그 글도 책에 넣으려고 공부핬는 스프링 3.0에 대한 이야기나 써야 했고. 다른 기술이나 책 내용 이외의 스프링 고급 기술에 대해선 깊이 파고 들어갈 마음의 여유를 가질 수 없다.

그런데 1,2장이 끝나고 슬슬 책을 쓰는 데 가속도가 붙기 시작하게 되니 마음에 빈틈이 생겼을까 자꾸 다른 재밌어 보이는 다른 기술에 눈이 가기 시작했다. 그래도 본격적으로 손을 대지는 못하고 있었는데, 어느날 한 출판사에서 연락이 왔다. "XXX 기술에 관한 책이 있는데 한번 번역하지 않으시겠어요?"라는 내용이었다. 내가 블로그에 그 기술에 대한 글을 몇 번 적은 적이 있는데 그것을 보고 내가 관심이 있어하지 않을까 해서 연락을 한 듯 했다. 갑자기 유혹이 몰려오기 시작했다.

일단 스프링 3.0에 맞춰서 책을 내기로 허락을 받았으니 마음에 여유가 조금 있었다. 게다가 3장 이후로는 엄청난 속도로 책이 써지는 것을 보면서 이 대로라면 3.0이 출시될 때 맞춰서 여유있게 책을 마무리 할 수 있을 것 같았다. 게다가 하루 종일, 일주일 내내 스프링 생각만 하면서 지내는게 너무나 지겨웠다. 뭔가 기분을 전환하고 다른 주제로 관심을 돌리는 시간이 필요할 듯 싶었다. 그래서 일단 긍정적인 답변을 했다.

그리고 나서 걱정이 됐다. 계약한지 2년이 넘도록 책도 마무리 못하고 있는 불량 저자 주제에 다른 책을 번역하는 것은 무책임한 짓이 아닌가 하는 생각이 들었다. 하지만 한편으로는 책을 쓰는 동안에는 다른 일을 안하겠다고 한 것도 아니고, 게다가 이미 스프링 3.0 출시에 맞춰서 책을 내기로 했으니 그 약속만 지킨다면 다른 일을 하든 책을 번역하든 괜찮지 않을까 하는 생각도 들었다. 한편으로는 포기할까 생각했지만, 그래도 자꾸 그 기술이 눈에 들어왔다. 사실 번역은 내 관심사가 아니다.  하지만 책을 번역하면 내가 관심이 있는 기술을 꼼꼼히 공부할 기회가 주어질 것 같아서 맘이 자꾸 끌렸다.

그래도 일단 김 부사장님께 말씀을 드리고 허락을 받는 것이 예의라고 생각을 했다. 그래서 연락을 해서 어렵사리 말을 꺼냈다. "번역 제의가 들어왔는데요. 제가 관심이 많은 주제라… 혹시 해도 될지.." 말이 미처 끝나기도 전에 대답이 돌아왔다. "절대 안돼요". 한마디라도 더 했다간 지난 2년간 제대로 책도 안쓰고 질질 끌던 것까지 함께해서 콤보로 혼날 것 같았다. "네".

책을 빨리 안 쓴 내가 잘못이지. 결국 그 출판사에는 개인 사정으로 번역은 못하겠다고 얘기했다. 그리고 더 열심히 더 빨리 스프링 책을 마무리 해야 겠다고 결심했다. 그 뒤로 무서운 속도로 책을 써나가기 시작했다. 그리고 1부의 내용이 제법 마무리 되가던 가을에 한국을 방문하게 됐다. 2부는 별로 걱정이 안됐다. 2부는 레퍼런스 식으로 각 기술의 사용방법과 기술선택에 관한 내용을 적으면 되기 때문에 별로 고민할게 없었다. 그동안 준비해놨던 방대한 양의 학습테스트 코드와 스프링의 깔끔한 API 문서, 레퍼런스 문서 등을 참고하면 1부보다 3배는 빠르게 쓸 자신이 있었다. 그러니 1부의 내용이 어느 정도 정리가 되가자 슬슬 눈을 딴데 돌리기 시작했다.

장인어른 팔순 때문에 평화와 아내와 함께 한국을 방문하기로 하고 준비하고 있던 어느날 또 다른 출판사에서 연락이 왔다. 역시 번역제안이었다. 기존에 내가 하고 싶었던 기술과 갈은 것이지만 다른 책이었다. 처음 제안받은 책은 바이블 성격의 두툼한 책이지만 두 번째 제안받은 책은 양도 작고 내용도 가벼운 입문자용 책이었다. 문장도 쉽고 코드도 많았다. 스프링을 잠시라도 벗어나야 숨이 트일 것 같은 기분으로 살고 있었기 때문이었을까. 덜컥 하겠다고 말해버렸다. 당시 스프링 3.0은 연말이나 되야 나올 스케줄로 진행되고 있었고 책은 그 때까지 충분히 마무리할 수 있을 것 같았다. 800페이지 짜리 책을 쓰기로 했는데 이미 500페이지가 넘었고, 2부는 더 쉽게 쓸 수 있을 것이라고 생각했으니까. 어쨌든 책을 먼저 마무리 하고 번역은 슬슬 진행하다가 스프링 책 원고를 넘기고 나서 집중적으로 하면 2010년 봄 쯤에 마무리 할 수 있을 것 같았다. 하루에 5페이지 정도만 한다면 2시간 정도 시간을 내면 될 듯 했고. 그 정도라면 평소에 책을 쓰다가 머리를 식히려고 보내는 시간 정도만 할애해도 충분할 듯 싶었다.

문제는 무서운 김 부사장님께 말씀드리는 것인데. 분명 몇달전에 안된다고 하셨는데 또 하겠다고 나오면 완전 반항으로 비칠듯 싶었다. 그래서 이를 어째야 하나 계속 걱정을 하면서 지내다가 한국을 방문하게 되었다.

가족과 함께 시간을 보내고 나서 돌아가기전에 김희정 부사장님을 만나기로 약속을 잡았다. 참석 가능한 KSUG 멤버들 몇 명도 자리를 함께 하기로 했다. 장소는 교보빌딩 1층의 모 식당에서 저녁 7시.

그런데 우연이겠지만 그날 같은 장소에서 몇 시간 전에 번역을 하기로 한 책을 낼 출판사 이사님과도 만나기로 했다. 그 장소가 출판인들에게 인기있는 장소였을까. 아무튼 그날 만남은 번역 계약서를 작성하는 자리였다. 일단 저술하는 책이 있으니 당분간은 그 책에 전념을 해야겠지만, 서서히 진행하다가 스프링 책이 완료되면 빠르게 마무리 하겠다고 말씀드렸다. 그 때까지 김 부사장님과 에이콘 직원분들 외에 내가 만났던 출판사 관계자는 I 출판사 사장님이 전부였다. 그런데 출판사 분들은 다들 왜 그리 친절하고 이해심 많고 저자나 역자를 끔찍히 배려해주는 데다 상냥하기도 한지. 그날 만난 이사님도 정말 천사같았다. 그러니 내가 거절을 못했을지도.

번역 계약을 마친후 서점에서 조금 시간을 보내다 저녁때 김희정 부사장님과 영회, 세원님 그리고 성철이 형을 만났다. 하필이면 앉은 자리도 오후에 번역 계약을 하러 다른 출판사 분을 만났을 때 앉았던 같은 자리였다. 김 부사장님을 만나면 번역 하기로 했다는 얘기를 꺼내야겠다고 마음을 먹긴 했는데 막상만나고 나니 말이 목에 걸려서 도저히 나오지가 않았다. 그날 내가 가장 많이 한 말은 그냥 "네".

게다가 그 날은 김희정 부사장님이 내 책에 대해서 이런 저런 주문을 많이 하셨다. 책의 분량은 800페이지 정도로 하기로 이미 여러번 합의를 보았지만 1부 내용이 조금 길어지는 것을 느끼면서 그보다 조금 더 늘어날 것 같은 느낌이 들었다. 김 부사장님은 만날 때마다 책 분량에 대해서 다시 확인하신다. 맨날 까먹으시는 것인지 아니면 저자가 욕심을 내서 분량을 늘릴까바 걱정되서 그러시는 것인지는 모르겠지만. 아무튼 그날 내가 "800정도 쓰려고 하는데요.. 근데.."라고 말이 꺼냈더니, "설마 800페이지 이상 쓰실려는 것은 아니죠?"라는 날카로운 목소리의 답변이 돌아왔다. 평소의 친절하고 상냥한 목소리와 톤이 일단 다른 데다 눈꼬리가 살짝 올라갔음을 눈치채고 나능 황급히 "물론 800이에요"라고 대답할 수 밖에. 뭔가 눈치를 채셨는지 "책을 쓸 때 뭘 넣을지가 중요한게 아니라 뭘 뺄지가 중요해요"라는 설명이 다시 이어졌다. 괜한 욕심부리지 말고 얼릉 마무리 하라는 얘기로 들렸다. 까짓거 일단 써보다가 800 페이지가 넘으면 일부 내용을 빼서 PDF로 만들어 따로 공개하면 되겠지라고 생각하면서 일단 그렇게 마무리.

평소와 다르게 그날은 실제적인 저술 방법에 대한 주의사항이 이어졌다. 대부분 내가 안지키고 있던 것들이었다. –_-;;;

"혹시 각주 넣으셨어요?". 물론 넣었다. 간단한 용어 설명이나 참고 정보는 각주로 뽑았다. 왠지 있어보이니까. 하지만 넣었다고 하면 혼날 것 같았다. 뻥을 쳤다. "아..니요…". 별 다른 설명이 뒤따르지 않았던 것으로 봐서는 그래야만 했던 것 같다. 이왕이면 저술을 시작할 때 그런 주의사항이나 가이드라인을 미리 주셨으면 좋았을텐데라는 아쉬움이 있었지만, 뭐 어쩌겠는가. 다시 호주에 돌아오자마다 각주는 모두 본문에 삽입하거나 박스에 넣어서 정리했고 새롭게 받은 가이드라인에 따라서 기존에 쓴 내용을 정리하느라 다시 며칠을 보내야 했다.

아무튼 처음으로 저술 방식과 형식 등에 대해서 한참 교육을 받고 나니 긴장이 더 됐는지, 결국 그날은 번역에 대한 얘기를 꺼낼 용기를 내지 못했다. 뻔뻔한 영회 같으면 그냥 얘기하고 말았을텐데.

 

내일 다시 적겠지만 그때 예상은 다 틀렸다. 스프링은 그해 12월에 나왔지만 내 원고는 올해 3월에야 겨우 마무리 했고, 생각보다 긴 교정시간을 거쳐서 5월에서야 겨우 초고를 넘길 수 있었다. 번역은 상당히 재밌는 경험이었고 책을 쓰는 것에 비하면 스트레스도 훨씬 적었다. 기대했던 대로 스프링과 완전히 다른 성격의 기술을 살펴보는 것은 머리를 식히는 데 최고였다. 물론 스프링 책에 우선순위를 두기로 한 결정은 그대로 지키려고 했고. 그래서 스프링 책의 마무리가 늘어지면서 번역작업도 같이 지연되었다. 결국 번역을 마무리 하고 초고를 보낸 것은 지난 7월이었다.

물론 김희정 부사장님께는 뒤늦게 다 실토했다. 한번 혼나고. 흑.

 

그 뒤의 이야기는 내일 계속.

두세 편이면 충분했을 것이라고 생각했는데 벌써 여덟 번째 이야기.

사실 그동안 내 이야기에 나온 사람들은 모두 내가 좋아하는 사람들이다. 책을 쓰는 동안에 나에게 나쁜 짓을 하거나 안좋은 영향을 준 사람들도 있지만 당연히 그런 사람들에 관한 얘기는 적고 싶지 않다. 그래서 여기에 언급된 사람들은 모두 내가 아끼는 사람들이고 여러모로 고맙게 생각하는 사람들 뿐이다. 어떤 상황에서도 프로의 모습을 잃지 않으시며 역자와 저자에 대해 미스테리한 마력을 가진 김희정 부사장님과 멋쟁이 김창제 수석님을 제외하면 나를 포함한 나머지 사람들은 모두 나사가 한두 개쯤 풀려있긴 하지만, 그래도 다들 마음이 따듯하고 알고보면 착한 사람들이다.

그동안 영회는 줄곳 나를 괴롭히는 악당으로 등장했지만, 그건 저술기간 동안 얼마나 힘들었는지를 설명하기 위해서 그런 사건(물론 100% 실제 있었던 일들이다)만 골라 넣었기 때문이지 사실 영회가 항상 나를 괴롭히기를 즐기는 나쁜 사람이기 때문은 절대 아니다. 이참에 실추된 영회의 이미지를 회복시켜주기 위해서 잘 알려지지 않은 영회의 선행을 하나 공개하겠다.

내가 다녀왔던 연변과기대 내의 IT교육원에는 종종 한국의 IT전문가들이 학생들을 위한 특강차 방문하곤 했다. 나도 프로젝트 교육 이전에 한번 특강을 위해서 방문한 적도 있고. 그래서 그 후로 여러 사람들에게 특강을 위해서, 또 새로운 자극과 휴식을 위해서 한번 쯤 연변을 방문하기를 권유해왔다. 보통 일주일 정도 방문을 하면 IT교육원 학생들을 위한 특강 시간을 한번 가지고 기회가 되면 학부 학생들이나 선생님, 교수님들을 위한 세미나를 열기도 한다. 대신 IT교육원은 영리를 목적으로 운영되는 기관이 아니기 때문에 모든 방문자들은 항공권을 포함해서 모든 경비를 스스로 지불해야 한다. 특강을 마치고 학생들과 식사를 할 때도 식사 비용을 방문자가 내는 것이 관례이다. 대신 IT교육원 선생님들이 시간을 내서 도문이나 용정 같은 곳에 데려가 관광시켜 주기도 하고, 현지의 독특한 음식을 맛볼 기회도 제공해준다. 무엇보다도 순수한 마음을 가진 학생들에게 특강을 통해서 무엇을 준비하고 어떻게 살아야할지 이야기 해줄 수 있는 기회를 가진다는 것이 가장 보람있는 일이다.

하지만 이런 얘기를 해줘도 대부분은 시간과 비용에 부담을 느껴서 선듯 가겠다고 나서지 못했다. 일년에 겨우 일주일 정도 휴가를 가지는 것도 쉽지 않은 빡빡한 환경에서 그 시간을 모두 들여서 특강을 위해 외국을 다녀오는 것은 쉬운 일이 아니다. 그런데, 그 얘기를 영회한테 했을 때 영회는 주저 없이 가보겠다고 했다. 마침 영회가 참여했던 큰 프로젝트가 하나 끝나고 프로젝트 포상 휴가가 기다리고 있을 때였다. 영회는 그 시간을 사용해서 연변을 방문하기로 했다. 기꺼이 자신의 시간을 기꺼이 들여서 처음 만나는 학생과 강사들에게 좋은 지식과 경험을 나누고 보람있는 시간을 보내고 돌아왔다. 그때 이야기는 영회 블로그(http://younghoe.info/937)에서 읽을 수 있다.

그런데 정작 내가 감동한 것은 그 후의 일이다. 영회가 특강을 했던 교육원 4기 학생들이 교육을 마치고 수료할 때가 되었다. 보통 졸업식 직전에 1박2일로 MT를 간다. MT 프로그램 중에 항상 빠지지 않는 것은 한국에 있는 IT전문가들의 만들어서 보내준 영상 축하 메시지를 보는 시간이었다. IT교육원을 설립하고 운영하는 데 가장 중요한 역할을 한, MSSQL의 대가인 원혁이 형이 주로 축하 메시지를 보내주는 단골이다. 그런데 4기 졸업 때는 영회도 자진해서 축하 메시지 영상을 만들어서 보냈다는 얘기가 들려왔다. 담당자를 이리 저리 꼬셔서 어렵사리 얻어낸 그 동영상은 지금 다시 봐도 참 감동적이다. 평소에 보이는 잘난척 하는 듯한 말투와 까칠한 눈빛은 보이지 않고 순박하고 착한 형이 동생들에게 해주는 듯한 따듯한 메시지가 담여있다. 특히 꾸미지 않은 쌩얼과 평소에는 잘 쓰지 않는 두툼한 안경을 쓴 모습이 일품이다. 이 영상만 봐도 영회가 얼마나 따듯한 마음씨를 가졌는지 알 수 있을 것이다.

하지만 겸손한 영회는 자신의 선행이 알려지는 것을 극도로 꺼려해서 그 동안 이 영상을 공개적으로 공유할 수 없었다. 하지만 아쉬움은 이제 그만. 가끔 영회가 술 마시고 들어와서 생각없이 블로그 글을 남겼다가 욕을 먹었던 일이나, N모씨에 의해서 한국의 3대 돌팔이라고 비난당해왔던 일 등을 생각하면 이쯤에서 잘못 알려진 이미지를 회복하는 것이 좋겠다고 생각된다. 그래서 쑥스러워 하는 영회의 만류에도 불구하고 그 영상을 내 블로그에 처음으로 공개한다. 이런 영상은 포털 메인에 올라가야 마땅한 건데… 다들 각자 블로그에 퍼가도 좋겠다.

 

영회의 명예회복을 시켜줬으니 다시 내 책 얘기로 돌아가자.

김희정 부사장님을 만나서 3.0으로 책을 내도 좋다는 허락을 받은 뒤 스프링원 아메리카 2008의 참석을 위해서 영회, 케누형, 기선이 등과 함께 미국으로 향했다. 나는 스프링소스의 컨퍼런스에 네번째로 참석하는 것이었다. 첫 번째 참석과 비교해 보면 한국, 중국, 일본 등지에서 온 아시아 개발자들의 참여가 늘었다는 것이 가장 인상적이었다. 2006년에는 아시아에서 참석한 사람은 나와 일본 NTT시스템즈에서 온 이시모로가 전부였는데 불과 2년 만에 D사와 S사에서 온 여러 명의 개발자들, 그리고 개인비용을 들여서 온 영회나 광남이 형 등을 포함해서 10명이 넘는 한국인들이 참여한 것을 보니 그동안 한국에서 스프링의 인기와 위상이 얼마나 높여졌는지 실감할 수 있었다.

컨퍼런스를 마치고 알라바마의 고객사에 일주일 방문해서 시스템을 점검해주고 다시 호주로 돌아왔다. 그리고 컨퍼런스에 맞춰서 공개된 스프링 3.0의 첫 번째 릴리스인 3.0 M1을 이용해서 1장의 내용을 열심히 마무리해나갔다. 기존에 JavaConfig이라는 이름으로 2년여간 질질 끌어오던 프로젝트가 스프링 3.0에서 코어 프레임워크로 통합되었다. 자바 코드를 이용한 설정 메타정보를 작성하는 기법은 내가 1장에서 추구해온 자바 코드에 의한 평범한 DI를 스프링을 이용한 프레임워크 기반의 DI로 옮기는 데 아주 좋은 연결고리가 되어주었다. 1장의 포인트는 바로 그것을 이해하는 데 있다.

1장을 끝내고 나니 자신감이 붙었다. 일단 코드를 손에 쥐니 그것을 이리 저리 만져가면서 그 과정을 옆자리에 있는 후배에게 설명하듯이 얘기를 풀어나갈 수 있었다. 보통 기술을 설명할 때 나는 먼저 간단한 그림을 종이에 그려가면서 코드의 구조와 동작하는 순서를 설명하는 습관이 있는데, 그런 내용이 필요하다 싶을 때마다 꼬박꼬박 다이어그램을 그렸다. 처음엔 UML 툴 같은 모델링 툴을 사용할까 했는데, 나중에 이미지로 옮겨와 붙이는 것도 귀찮고, 내가 자유롭게 그림을 그리고 싶을 때 불편할 듯 싶어서 손이 많이 가고 시간은 더 들지만 워드의 그림툴을 사용해서 모든 다이어그램을 만들었다.

1장은 그 뒤로 가장 많이 다시 손을 봤지만 지금까지도 제일 아쉬움이 남는 장이다. 가장 중요하지만, 가장 쉽게 써야 했고, 가장 많은 용어가 갑자기 튀어나와서 이를 수습해야 했고, 가장 많은 코드의 변화가 있는 장이다. 사실 1장은 스프링을 통해서 만들어지는 코드가 어떤 것이라는 기본을 소개하는 장이고, 2장부터 7장까지는 1장에서 소개한 내용을 다시 다양한 엔터프라이즈 기술 영역에서 응용하는 방법을 보여주는 것이다. 사실 그게 스프링의 전부이고, 그것만 잘 알면 스프링의 기술을 빠르고 쉽게 이해할 수 있다. 그래서 가장 많은 정성을 쏟기도 했고, 가장 많이 뜯어고쳐야 했다.

2장은 1장에서 main() 메소드로 만들었던 원시적인 테스트를 JUnit을 이용해서 전환하면서 자동화된 테스트의 필요성을 설명하고 테스트 코드를 작성하는데 필요한 기초적인 지식을 다루었다. 2장은 1장에 비해선 부담없이 쓸 수 있었다. 2장까지 모두 마무리하고 나니 2009년도 절반 가까이 흘렀다.

먹고 살아야 하니 그 사이 크고 작은 일도 맡아서 해야 했다. 그래서 예상했던 것보다 시간이 많이 소요됐다. 그래도 급하게 다음 장으로 넘어가지 않고 책을 쓰는 기본 틀을 다지는 데 많은 시간을 들이는 것이 낫다고 생각했다. 이야기를 풀어나가고 그에 맞게 코드와 다이어그램 등을 넣는 방법에 익숙해지고 나니 그다음 부터는 속도가  빨라졌다. 3장은 1장의 2/3쯤 되는 적지 않은 분량인데도 단 8일만에 완료했다. 정말 흐름을 타고 술술 써내려져가는 느낌을 받았다. 상대적으로 양이 적은 4장은 단 4일만에 끝냈다. 마틴 파울러와 로드 존슨이 트위터에서 책을 쓰다가 어느 순간 흐름을 타는 것을 느낄 때가 있다고 얘기한 적이 있는데 그때가 바로 그런 느낌이었다. 5장도 적지 않은 분량임에도 11일만에 끝냈다. 6장은 1부에서 가장 양이 많은 장이고 가장 난이도가 높다. 지금까지 누구도 하지 않았던 새로운 방법으로 난해한 AOP를 설명하려고 노력했다. 그러다 보니 등장한 코드(리스트) 갯수만 100개이고 다이어그램도 25개나 됐다. 보통 코드를 만들고 다듬는 시간이 절반, 그리고 그 코드를 다시 처음부터 풀어가면서 글로 남기는 시간이 절반 정도 들었다. 6장에 사용할 코드를 만들고 다듬은 후에 그 내용을 써내려갈 때는 정말 쏟아져 나오는 생각과 말을 정신없이 타이핑한다는 느낌이 들 정도였다. 그렇게 150페이지 분량의 내용을 준비하고 작성 완료하는데 한달이 채 걸리지 않았다.

그러는 사이 사촌동생의 소개로 작지만 매우 급한 개발 프로젝트 하나를 맡게 됐다. 그 프로젝트를 진행하는 한달 가까이는 책에 손을 대지 못했다. 그런데 프로젝트를 하느라 종일 코딩과 테스트에 매달려야 했지만 그 사이 내 머리 속에선 그 다음에 풀어갈 내용들이 계속 흘러다녔다. 완전히 흐름을 탄 느낌이었다.

그 사이 평화는 처음으로 어린이집에 다니게 되었고, 아내는 호주를 떠나면서 중단했던 대학원을 마저 다니기로 했다. 아내가 학교를 가는 날은 평화를 돌보고 어린이집에 데려다 주고 오고, 돌보는 일이 모두 내 책임이었다. 어린이집을 가지 않는 날은 온 종일 집에 있는 평화를 상대해야 했다. 가장 힘든 일은 밥을 먹이는 것과 낮잠을 재우는 것. 평화는 먹는데 취미가 없다. 게다가 입맛이 까다로워서 주는 대로 먹지 않는다. 보통 2-3가지 음식을 준비해서 시도해야 겨우 한가지 먹을까 말까.  음식을 들이밀어도 아예 입도 대지 않으려는 때가 더 많았다. 평화를 키우면서 들어가는 수고의 70%쯤은 밥을 먹이는데 들어갔다. 까다로운 입맛에 맞춰서 음식을 준비해야 하고, 한번 시도해서 안되면 다시 다른 음식을 준비해야 했다. 아무거나 주면 잘 먹고 자기가 먼저 밥 달라고 한다는 애들 얘기를 들으면 그렇게 부러울 수가 없었다. 물론 평화가 더 어렸을 때는 주는 대로 잘 받아먹었고, 우리도 음식을 골고루 먹이려고 제법 많은 노력을 들였다. 인스턴스나 미리 준비된 음식은 거의 먹이지 않고 다양한 재료를 골고루 먹게 하려고 노력했다. 하지만 입맛 까다로운 나를 닮은 평화는 자기가 음식을 거부할 수 있음을 알게되면서부터는 쉽게 입을 열지 않았다. 게다가 자기 그릇에 놓인 음식이 맘에 안드는데 자꾸 먹으라고 채근하면 짜증이나서 음식이나 그릇을 던져버리는 일도 있었다. 그때마다 혼을 내고 타일러봐도 별 소용이 없었다. 그렇게 하루 하루가 전쟁이었다. 잠을 재우는 것도 쉽지 않았다. 낮잠을 제대로 못자면 저녁 때 힘들어하고 짜증을 많이 내기 때문에 낮잠을 꼭 재워야 하는데, 이게 타이밍을 놓치면 쉽지 않다. 정 안되면 차를 태우고 한 바퀴 돌면서 재우기도 했는데 어떨 때는 한시간 넘게 운전을 해도 잠이 들지 안을 때도 있었다.

아내가 학교 가는 날은 그렇게 평화랑 종일 씨름하다가 조금씩 틈이 날 때 잽싸게 책을 쓰거나 일을 해야 했다. 어떨 땐 짜증을 참지 못하고 한바탕 혼을 낸 뒤에 펑펑 우는 평화를 붙잡고 달래며 시간을 보내야 했다. 태어나서 처음으로 엄마랑 떨어져 지내는 시간이 쉽지 않았을 텐데, 게다가 어린이집이라고 일주일에 이틀씩 보내는 곳은 집에서 듣던 것과 전혀 다른 언어로 이야기 하는 선생님과 친구들 뿐. 이런 저런 스트레스가 대단했을 텐데 그것을 다 받아주지 못하고 종종 화를 냈던 것이 지금도 미안하다.

책을 쓰면서 가장 힘들었던 순간은 평화가 방문을 열고 와서 자기와 놀아달라고 내 손을 잡아 끄는데 그것을 거절해야 했을 때다. 어떨 땐 방문을 잠궈보기도 했는데, 그러면 방문 앞에서 문을 두드리면서 ‘아빠’라고 수십번씩 목놓아 부르기도 한다. 아빠가 필요한데 자기랑 놀아주지 않고 손을 밀어내며 키보드만 두드리는 아빠가 얼마나 원망스러웠을까.

아무튼 그렇게 쉽지 않은 환경에서 꾸역꾸역 원고를 채워나가던 중에 한국을 다시 방문할 기회가 생겼다. 이번엔 일이나 컨퍼런스 때문이 아니라 장인어른 팔순 잔치 때문이었다. 사실 잔치는 장인께서 원치 않아서 따로 하지는 않았지만, 팔순인 만큼 온 가족이 다 모이기를 강력히 희망하셔서 미국에 사는 큰 처형과 호주에 있는 우리 가족을 포함해서 온 가족이 모이는 시간을 가졌다.

 

오늘은 오랜만에 비가 와서 그런지 날씨도 꿀꿀하고 기분도 왠지 울적해서 글도 잘 안써진다. 오늘 얘기는 여기서 대충 줄이고 내일 다시 더 써야겠다. 그래도 이제 끝이 보인다.

영회가 생각없이 던진 돌에 정통으로 맞아 쓰러지고 나서 시간이 조금 흐르니 오히려 마음이 편해졌다. 어짜피 내가 아무리 용을 쓰고 책을 잘 써봤자 영회같은 인간들이 분명히 나타나서 이런 저런 시비를 걸 것이 분명했다. 어짜피 어떻게 해도 욕먹을 거라면 그냥 내가 쓰고 싶은 대로, 내가 하고 싶은 얘기를 하면 되겠다고 생각하니 그때까지 가졌던 긴장감이 다 풀렸다. 잔뜩 주고 있던 힘이 빠지고 나니 오히려 그 다음은 쉬웠다.

날려버린 1장을 처음 쓸 때 사실 힘들었다. 그 1장에는 코드 한줄 나오지 않는다. 대신 3만피트 상공으로 올라가서 스프링 세계를 내려다보며 스프링이 이렇게 생겼네라고 구름 위에서 얘기하듯이 설명하는 내용이다. 그래서 신경쓸 것은 단어, 표현 등이었다. 함축적인 단어를 어떻게든 잘 골라서 이런 저런 스프링의 특징을 깔끔하게 묘사해야 할텐데라는 고민으로 대부분의 시간을 보냈다.

나는 그런 식의 얘기가 편하지 않다. 내가 가장 편한 시간은 코드를 앞에 놓고 코드에 대해서 이야기 할 때다. 열 줄 정도의 코드만 있어도 재미나게 한 시간쯤은 수다를 떨 수 있다. 지난 27년간 거의 매일 만들고 다듬고 뜯어보고 감상해왔던 것이 코드다. 그래서 누군가에게 기술을 설명해줄 때도 코드를 놓고 이야기해야 편하다. 특히 어설픈 코드를 만들어 놓고 그것을 다듬고 발전시켜서 아름다운 코드로 만들어내는 과정을 즐기는 것이 좋다.

그래서 다시 1장을 쓰면서 가장 먼저 코드 하나를 들이 밀었다. 초난감 DAO. 왜 하필 DAO로 시작했을까? 사실 1장은 스프링의 DI를 설명하려고 쓴 것이다. 보통 스프링 서적이나 교육시간에는 다형성이 적용가능한 도메인 모델을 가져다가(예를 들면 찬욱이가 잘 쓰는 피자 주문 어쩌고 같은) XML로 설정을 바꿔가며 DI하는 모습을 보여주는 것이 일반적이다. 하지만 나는 그런 현장감이 없는 코드가 싫었다. 개발자라면, 심지어 이제 막 자바 교육과정을 마친 초보 개발자라도 쉽게 이해할 수 있는 익숙한 코드를 가지고 설명하고 싶었다. 그래서 선택한 것이 가장 간단하고 단순한 DAO 코드이다. DAO 코드만 가지고도 DI를 설명하기에 충분하다.

 

나는 이미 이전에 간단한 DAO 코드를 가지고 스프링의 DI를 설명해본 경험이 있다. 2007년 (북반구) 여름에 연변자치주 내의 연길시에 있는 연변과학기술대학(YUST)에 방문한 적이 있다. 그냥 방문이 아니고, YUST의 IT교육센터에 초빙강사쯤으로 간 것이다. 거기서 2주정도 체류하면서 조선족 대학졸업자를 대상으로 진행하던 4개월간의 합숙 교육과정의 마지막 단계인 프로젝트 실습시간을 맡아서 자바의 기초를 이제 막 배운 학생들과 함께 교육과정을 마무리 하는 프로젝트 교육을 진행했다. 당시 교육과장에 참여했던 20여명의 학생 중에서 소수만이 북경에 있는 SI업체에 취업이 확정된 상태이고 다른 학생들은 아직 일자리를 찾지 못하고 있어서 기운을 잃고 있던 상황이었다.

YUST의 IT교육센터는 YUST가 그렇듯이 조선족 젊은이들에게 양질의 교육 프로그램을 제공해서 중국 사회, 나가서는 세계적으로 실력있는 전문가를 만들어내려는 목적으로 2007년 초에 설립되었다. 매일 새벽 운동으로 시작해서 밤 12시까지 교육과 실습 시간을 가지고 학교내의 기숙사에 머물면서 강도 높은 교육을 진행한다. 이 교육센터를 설립하고 강사로 일하는 분들은 모두 자원봉사자들이다. 다들 한국에서 이름을 날리던 IT전문가, 유명 강사들인데 자신의 삶에서 몇 년의 시간을 떼어서 자원의 제약이 많은 지역에 살고 있는 사람들에게 지식을 나누고 꿈을 심어주기 위해서 아무런 댓가도 없이 이국땅에 모인 존경스러운 분들이다.

아무튼 거기서 보낸 2주간의 시간은 참 행복했다. 학생 대부분은 IT전공자가 아니다. 심지어 영어를 전혀 못하는 사람도 있었다. 연변자치주 내의 조선족 학교에 다녔던 학생들은 중고등학교 시절에 영어가 필수 과목이 아니었다고 한다. 보통 일본어를 더 많이 공부했고, 대학에 진학해서야 교양과목 수준으로 영어를 배운 사람들이 많다. 그래서 일부는 대졸자임에도 알파벳에도 익숙하지 못한 사람들이 있었다. 그래서 알파벳과 영어단어를 읽는 것부터 가르쳐야 했다.

이 교육센터의 특징은 24시간 선생님과 학생들이 함께 하는 것이다. 물론 가족이 있는 선생님은 학교 주변의 숙소에 머물긴 하지만, 정규 교육시간이 끝나고 집에 가서 저녁 식사를 하고 야간 실습시간이 되면 다시 학교로 올라와 12시, 심지어는 새벽까지 그날 공부한 내용을 학생들이 실습해보면서 막히는 것이 있으면 옆에 붙어서 가르쳐 주고, 개인적인 상담도 해주기도 했다. 일부 학생들는 ABC부터 공부해가면서 그렇게 열심히 자바를 배웠다. 그 와중에 SCJP시험도 공부해서 대부분 SCJP도 딴 상태였다(학생들을 받아주기로 한 업체의 요구사항의 하나였다고 한다). 하지만 막상 내가 프로젝트 수업을 어떻게 진행할까 고민하면서 그동안 공부한 내용을 살펴봤을 때는 참 막막했다. 자바 언어와 JDBC, DB(SQL), HTML/자바스크립트, 서블릿, JSP 모델1 정도를 배운 것이 전부였다. 사실 맨땅에서 그만큼이라도 공부한 것은 대단했다. 나름 공부한 내용은 끊임없이 실습하고, 반복해서 학습했기 때문에 익숙했다.

4개 조를 나눠서 주어진 요구사항을 충족하는 웹 애플리케이션을 만들도록 했다. 스프링 따위는 사용할 엄두도 낼 수 없었고, 내가 하루 밤 사이에 급조해서 만든 초간단 MVC 프레임워크를 사용해서 모델2로 만들도록 했다. 매일 새벽 1시에 건물을 관리하는 분이 나가라고 찾아올 때까지 함께 코드를 만들어가면서 그렇게 열흘 정도를 보내고, 기대 이상의 멋진 결과물을 만들어서 YUST 전산과 교수님들을 모아 놓고 발표회를 가질 수 있었다. 내가 일했던 회사의 개발자들에 비하면 다들 형편없는 수준의 초보자였지만, 하나도 놓치지 않고 배우고자 하는 열정과 끈기가 대단했고, 교육해주는 강사에 대한 고마운 마음과 존경심이 대단했다. 참 행복한 시간이었다. 처음엔 취업이 되지 않아서 실망하고 열정도 잃었던 학생들이 코드를 만들어나가면서 동작하는 애플리케이션을 보고 환호하고 서서히 자신감을 찾아나가고 미래에 개발자로서 살아갈 꿈을 꾸는 모습을 보는 것이 즐거웠다.

다행히 대부분의 학생들은 북경과 상해의 여러 업체에 취업이 되었고, 일부 학생들은 한국 SI업체의 북경지사에 취직해서 프로젝트 하러 한국에 다녀가기도 했다.

그런데, 기껏해야 내가 만든 간단한 MVC 프레임워크(URL 컨트롤러 매핑은 프로퍼티 파일을 사용하게 했다)와 원시적인 JDBC API로 만들어진 DAO를 이용하는 코드를 만들어본 경험이 전부인 초보자들인데, 일부 SI업체들은 전혀 교육도 시켜주지 않은 채로 스프링을 써야하는 프로젝트에 마구 투입했다. 내 생각에는 아마 프로젝트에 비용을 맞추기 위해서 신입들을 머리수 채우는 용도로 넣은 것이 아닌가 싶다. 아무튼 그렇게 여러 사람들이 스프링 개발을 해야 하는데 막막해 하고 있다는 얘기를 전해 들으니 가슴이 아팠다. 그렇다고 내가 뭔가 뾰족하게 도와줄 방법도 없었다. 그저 책과 자료를 알려주고 차근차근 공부하라고 할 수 밖에. 하지만 내가 아는 스프링 책들과 인터넷의 자료들은 그저 자바기초와 JDBC, JSP 정도를 아는 경험없는 초보 개발자들이 쉽게 독학으로 스프링을 익힐 수 있는 것들이 아니었다.

그러던 즈음에 IT교육센터에 보조강사로 남은 졸업생의 한 명인 향화가 스프링을 알려달라고 연락이 왔다. 향화는 YUST를 졸업하고 유학을 준비하던 즈음에 강사로 간 분의 꼬임에 넘어가 IT교육센터에 입학했다. 내가 가르쳐본 경험으로는 가장 우수한 학생이었다. 한족이지만 한국어를 제법 잘해서 교육을 함께 받았던 소강이와 함께 가장 학습능력이 뛰어나고 프로그래밍 실력이 좋은 학생이었다. 그래서 마음만 먹으면 얼마든지 원하는 회사에 갈 수 있었지만, 자기는 연길에 남아서 후배들을 가르치는 일을 하고 싶다고 취업을 포기하고 보조강사로 IT교육센터에 남은 기특한 아이였다. 막상 보조강사는 하고 있지만 교육센터의 프로그램은 IT 기초소양교육과 자바 프로그래밍 기초였기 때문에 스프링과 같은 고급 기술을 배울 기회가 없었다. 그런데 막상 현장에 나가서 일을 하는 졸업생들은 스프링은 어디가나 다 쓰기 때문에 꼭 배워야 한다는 얘기를 전해오고 있었으니, 자신도 스프링을 좀 준비해둘 필요가 있다고 생각한 것이다.

내가 놀랐던 사실 하나는 2007년 여름에 중국 아마존 사이트에 등록 되어있는 스프링 2.0 서적이 무려 20권이나 있다는 사실이었다. 한국에는 2.0책이라곤 SiA 2판이 겨우 나왔을 때였는데 말이다. 그만큼 중국에서는 스프링을 많이 사용한다. 뭐, 일본도 그렇고 전세계가 다 그렇지만. 아무튼 한국과 비교했을 때 당시 중국의 스프링 도입률이 훨씬 높았다.

아무튼, 당시 나는 서울에서 일을 하고 있었고 향화는 중국 연길에 있었다. 교육을 해준다고 해도 기껏해야 스카이프와 메신저가 전부였다. 그나마 코드는 SVN을 이용해서 서로 공유해서 볼 수 있었지만. 향화는 공대출신이기는 하지만 IT전공자가 아니었으니, 자바 지식이라곤 교육센터에서 4개월 배운 것이 전부였다. 따라서 자바 언어 기초, JDBC/DAO, 서블릿/JSP 정도는 확실하게 알고 다룰 수 있는 실력이지만 그 외의 프레임워크니 기술은 전혀 사용해본 경험이 없었다.

그래서 향화에게 어떻게 스프링을 가르쳐 줄까 고민하다가 생각한 것이 그나마 향화가 가장 익숙하고 많이 만들어본 DAO였다. 초보 개발자들이 교육센터 등에서 만드는 DAO 수준은 뭐 뻔하다. try/catch/finally라도 적용했으면 다행이고, 그렇지 않은 경우도 많았다. JDBC API를 사용해서 돌아만 가는 CRUD만 만들 수 있어도 잘하는 것이었으니까. 물론 향화는 내가 교육하면서 try/catch/finally나 안전한 DAO를 만드는 방법에 대해서 확실하게 교육했으니 잘 알고 있었지만.

그래서 향화가 그나마 잘 아는 DAO 코드를 하나 만들어줬다. 그리고 그 코드의 문제점이 무엇인지 찾아보고 그 코드를 매일 매일 조금씩 개선하면서 OO적인 코드로 다듬는 것을 알려줬다. 그렇게 짬짬이 원격 교육을 하면서 서서히 DAO코드를 다듬어서 DataSource에 대한 DI도 적용하고 템플릿/콜백도 만들어가는 식으로 설명을 해줬다. 그냥 XML 설정파일 만들고 DAO와 DataSoruce 빈을 등록하고, CRUD는 JdbcTemplate가져다 쓰고, web.xml에 컨텍스트로더리스너 등록해서 돌리라고 가르쳤으면 일주일이면 충분했을 것을 몇 달에 걸쳐서 설명을 해줬다. 하지만 그렇게 스프링을 이해하고 배우는 것이 나중에 내가 더 이상 스프링을 가르쳐 주지 못하고 혼자서 공부할 때 분명 도움이 될 것이라는 확신이 있었다. 결국 나중에 나는 너무 바빠서 교육은 기선이에게도 부탁했다. 교육센터의 보조강사는 기숙사에서 함께 생활하면서 24시간 학생과 함께 지내야 한다. 특히 실습과 시험준비 등으로 새벽까지 남아서 공부하는 학생이 있으면 끝까지 옆에 붙어서 도와줘야 한다. 그래서 나중에는 너무 바빠서 더 이상 충분히 공부할 시간이 없어서 스프링 공부는 흐지부지 끝나고 말았다.

 

다시 1장을 쓰기로 마음먹고 무엇인가 코드를 일단 던져 놓고 시작을 해야겠다라고 생각했을 때 향화에게 스프링을 가르쳐 주던 생각이 났다. 그때 사용했던 DAO코드를 개선해 나가면서 스프링을 적용하는 과정을 이용하면 되겠다는 생각이 들었다. 김희정 부사장님이 만날 때마다 하셨던 얘기는 "책을 쉽게 써야 한다"였다. 보통 처음 책을 쓰는 사람은, 욕심에 책을 어렵게 쓰는 경향이 있다. 자기 주변에 잘 하는 사람들이 많이 있을테니 그 사람들이 봐도 있어보일만한 책을 쓰려는 욕심이 들기 쉽다. 또, 독자들이 자기 주변의 사람들 처럼 이미 선지식이 충분히 있을 것이라고 착각하기도 쉽다. 당연히 JUnit도 척척 쓸 줄 알고, 자바 언어와 디자인패턴도 완벽히 꿰고 있을 것이라고 착각하기 쉽다. 하지만 대부분의 독자는 그렇지 않다. 나도 현장을 다니면서, 나름 유명한 기업의 개발팀 사람들이 JUnit을 들어본 적도 없다는 사실에 놀라기도 했다. 가장 기본이라고 생각하는 자바 콜렉션 프레임워크의 semantics에 대해서도 제대로 이해를 못하는 사람도 많았다. 당장 현장에서 돌아가는 애플리케이션을 만들고 관리하는 것이 주업무였고, 컨설턴트나 아키텍트가 만들어준 템플릿을 이용해서 기계적인 반복 코딩을 했기 때문일 수도 있고.. 뭐 이유는 많겠지만.

물론 주변에서 "한국에도 이제 중고급자(만)을 위한 책이 나와야 하자나요. 마음 것 고급내용으로 어렵게 쓰세요"라고 꼬시는 사람들이 있었다. 하지만 그럴 때마다 어려운 책을 붙잡고 씨름하다 막막해 하는 향화나 교육센터 졸업생들을 생각해봤다. 그래서 그들도 볼수 있도록 책을 쓰자고 결심했다. 또는 그런 비슷한 수준의 초보 개발자들, 또는 자바 입문자들도 공부할 수 있도록 써야 겠다고 생각했다. 물론 자신을 고수라고 생각하는 일부 개발자들은 "책이 너무 쉽다. 블로그 글을 보고 그 수준으로 기대하고 샀는데 사기 당했다"라고 원망할 수도 있을 것이다. 물론 치밀한 나는 그런 사람들을 위해서 중간 중간에 난이도가 높은 내용을 틈틈히 박아두기는 했지만.

아무튼, 그렇게 해서 1장을 썼다. 막상 코드를 꺼내놓고 얘기를 풀어 나가니 줄줄 잘 써졌다. 코드만 만지면 이게 무슨 짓을 하는 것인지 정리가 안될테니 중간 중간에 이런 저런 이론을 가지고 배경을 설명하려고 노력했다. 물론 그런 이론 얘기가 나오면 경기를 일으키는 개발자들도 있기 때문에 이런 얘기는 몰라도 그만이라고 둘러대고 넘어가야 했지만. 사실 스프링의 DI를 XML 설정파일이라고 착각하는 개발자들이 많다. 소위 대안 언어씩이나 한다는 사람들이 스프링도 별거 없다고 까면서 흔히 꺼내는 것이 바로 XML 설정파일 같은 거 써야 하는 자바 언어의 후진성에 관한 얘기다. 물론 다 DI의 D자도 제대로 모르기 때문에 나오는 헛소리다. 스프링이 말하는 DI는 평범한 프로그래밍 원리일 뿐이고 자바 언어만으로 충분하다. DI로 검색하면 DI에 대한 정의 – 애플리케이션 코드와 어셈블러(의존관계 설정의 책임을 맡은 놈)를 분리해서 개발하는 방법 – 가 널려있는데, 그걸 자꾸 언어의 한계 때문에 XML 설정파일을 사용하는 프레임워크가 필요한 기술이라고 왜곡 시키는 사람들을 나는 도무지 이해할 수 없다.

그래서 XML 한 줄 없이, 스프링 코드 전혀 없이 DI를 적용하는 모습을 보여주고 싶었다. 그래서 100페이지쯤 되는 1장의 절반이 될 때까지 DI를 줄곳 설명하고 코드를 보여주지만 스프링은 전혀 등장하지 않는다. DI에 스프링이 필요한게 아니니깐 등장할 필요도 없다. 그리고 나서 DI컨테이너(또는 프레임워크)로서 스프링을 활용하면 그 때까지 평범한 자바로 했던 DI작업이 좀 더 편해진다는(물론 규모가 있는 DI적용의 경우에) 설명을 곁들여서 DI와 DI프레임워크의 차이점을 보여주려고 했다.

제법 빠른 속도로 그렇게 1장을 써나가던 12월 초에 드디어 스프링원 아메리카 참석차 한국을 거처 미국으로 떠나게 되었다.  친절한 민호가 나와 기선이 모두 스프링 컨퍼런스에 다녀올 수 있도록 후원해주겠다고 했다. 가는 길에 한국에 일주일 먼저 들리기로 했다. 물론 이 선택은 나중에 후회를 했는데, 갈 때는 한국에 스톱오버를 해서 쉬었다 가서 괜찮았지만 올때는 바로 갈아타고 호주로 오느라 거의 24시간 가량 쉬지 않고 비행기를 타야했고, 엉덩이는 거의 의자 모양(비상구 좌석)에 맞게 네모로 변했고, 완전 녹초가 되버리고 말았다. 왜 어떤 사람들이 비행기에서 협소공포증을 느끼고 뛰어내리고 싶어하는지 살짝 이해가 가기도.

 

아무튼 한국을 간다는 소문이 나자 김희정 부사장님이 만나자고 연락이 왔다. 두둥.

호주로 갑자기 떠났던 불량 저자가 온다고 하니 이 참에 확실히 교육시켜야 겠다고 벼르고 계실거라는 생각이 들었다. 덜덜덜. 그래도 어쩌겠는가. 시내에서 영회와 때마침 한국에 온 성훈이 부부와 함께 김희정 부사장님을 만났다. 성훈이는 MIT에 있던 2007년부터 같은 팀에서 함께 일을 한 적이 있어서 친하긴 했지만 한번도 얼굴을 본적은 없었다. 다른 사람들과 함께 만나서 다행이었다. 설마 3자 앞에서 너무 면박주지는 않을테니까.

차마 진도가 어느정도 나갔다는 얘기는 못했다. 대신 용기를 내서 스프링 3.0이 내년(2009년) 봄에 나온다는데 이왕이면 3.0에 맞춰서 책을 내는게 어떻겠는가 하고 얘기를 꺼냈다. 이미 2.5 책들은 여러 권이 나와서 팔린 상태였고 3.0이 나오는 마당에 2.5 책을 내버리면 뒷북치는 꼴이 되버리는 것이 아니겠냐는 논리였다. 물론 나는 어떻게든 가능한 시간을 벌려는 속셈이었다. 마치 책을 마무리 해가지만 3.0을 기다렸다가 3.0 맞춰서 수정해서 빠르게 3.0 책으로 내는 것이 마케팅 측면에서도 더 낫지 않겠느냐는…  개발자 출신 저자의 얕은 속셈을 다 꿰뚫어 보고 있지만 그럼에도 항상 상냥한 김희정 부사장님은 예상과 달리 "2.0 책 낸다고 계약했는데 3.0까지 가면 어떡해욧"이라고 하지 않으시고 "그럼 3.0에 맞춰서 내는게 좋겠어요. 사장님께도 그렇게 말씀드릴께요"라고 답하셨다. 그런 표현은 없었지만 기획한 책이 빨리 안나온다고 사장님께 혼난다는 눈치였다. 호랭이 희용이가 김 부사장님께 시달린다고 얘기할때와 비슷한 상황이었다. 한편으로는 "도대체 어디까지 질질 끌려나 한번 두고 보자. 3.0이든 4.0이든 어디 한번 해봐라"는 자포자기한 마음에서 나온 얘기가 아니었을까 생각이 들기도 했다.

어쨌든 시간을 좀 벌었으니까 일단 한숨 돌렸다.  점심으로 먹던 중국 요리가 목에 반쯤 걸려있었는데 갑자기 쑥 내려가는 느낌이었다.

스프링 3.0이 2009년 4월에 나온다는 것이 스프링소스의 공식 발표였다. 그런데, 솔직히 말하자면 스프링소스는 약속한 날자에 한번도 스프링 새버전을 릴리스를 한 적이 없다는 사실을 나는 너무 잘 알고 있었다. 그러니 4월에 나온다고 하면 빨라야 8-9월에나 나올 것이 분명했다. 하지만 그런 얘기는 차마 할 수가 없었다. 그때문에 더 죄송했지만 내 코가 석자라.

아무튼 3.0에 맞춰서 내는 것을 허락받고 나니 마음이 한결 가벼워졌다. 물론 김희정 부사장님은 "굳이 정식버전이 다 나오지 않아도 책을 내도 괜찮아요. 일단 RC버전이라도 최대한 내용을 맞춰서 일단 책을 내고, 2쇄 할 때 최종 버전이 나오면 좀 더 보충하는 식으로 해도 돼요"라고 설명해주시면서 릴리스 일정 핑계대서 질질끌지 말고 가능한 빨리 내야 한다는 눈치를 주시긴 했다.

 

하지만 스프링 개발팀은 내 예상을 훨씬 넘어서 처음 약속보다 8개월이 지난 12월에야 3.0을 내 놓았다. 내 책은 그 뒤로 다시 8개월이 지나서 나오게 되었고.

본격적으로 책의 내용을 써내려간 이야기. 그리고 다음 해 9월 한국 방문과 그 때 벌어진 KSUG 회장 전격 교체작전 등등에 대해서는 내일 다시.

© 2017 Toby's Epril Suffusion theme by Sayontan Sinha