이머전스란 전체는 부분의 합보다 크게 되는 현상을 말한다. 혼자서는 도저히 발휘할 수 없는 개체들이 하나의 프레임워크에 융합되어 거대한, 새로운 힘을 만드는 것이다. 하지만 n개의 개체들이 모여 n개를 초과하는 무엇을 만들기란 어려운 일이다. 그럼에도 불구하고 JBoss를 비롯한 우수한 프레임워크들은 이러한 기적을 이뤄내고 있다. 특집 2부를 통해 JBoss와 JBoss를 이용하는 애플리케이션이 이머전스 되는 모습을 분석해 보자.
이제 개발자 혼자서 프로그램의 처음과 끝을 모두 개발하는 시대는 지났다. 시스템 라이브러리나 프로그래밍 언어에서 지원하는 라이브러리를 제외하더라도, 우리는 각종 코드 샘플, 유틸리티 라이브러리, 미들웨어 서비스, 프레임워크 등을 이용하여 애플리케이션을 개발한다.
어차피 소프트웨어 개발의 철학은 재사용 가능한 것들을 이용하여 그 이상의 부가가치를 창조하는 작업이다. 따라서 이미 개발된 품질 좋은 프로덕트들을 이용함으로써 생산성을 높이는 일은 개발자의 숙명이 된 셈이다.
사실 필자는 이 ‘숙명’이 불편하다. 기술적으로 매력적인 부분들은 이미 오픈소스나 상용 솔루션으로 제공되고 있는 탓이다. 또한 이미 만들어진 프로덕트를 ‘소비’하여 개발해야 하는 비즈니스 애플리케이션 일변도의 우리나라 개발 지형이 개발자가 기술적으로 더 연구 개발 할 기회를 박탈하기 때문이다.
원천 기술의 생산은 외국에서하고 우리나라는 단지 그 기술을 소비와 가공을 통해 진행하기만 하는 프로젝트 환경이 불편하다. 결과적으로 한국에서 대부분의 프로젝트에는 기술의 심층을 잘 이해하는 엔지니어보다 이미 만들어진 라이브러리를 잘 이해하고 다룰 수 있는, 즉 생산력을 가진 개발자를 요구하고 있다.
이런 문제를 해결할 대안으로 오픈소스 개발을 통해 기술적인 욕구와 연구를 해야 한다는 것이 필자의 소견이다.

요즘 필자는 프레임워크를 볼 때 이머전스(창발)란 개념이 떠오른다. 앞서 설명한 바와 같이 프레임워크를 이용함으로써 더욱 완성된, 새로운 부가가치의 애플리케이션을 창조할 수 있기 때문이다. 이것은 이머전스에서 ‘전체는 부분의 합보다 크다’는 명제에 충실하다.
프레임워크를 잘 활용하면 1+1의 결과가 2를 초과하는 효과를 낳는다. 또한 JBoss나 스프링(spring), 하이버네이트(Hibernate) 같은 큰 프레임워크의 내부를 보면 이들도 다른 프레임워크들을 조합하여 이머전스 되는 현상을 확인할 수 있다.
혼자서는 도저히 발휘할 수 없는 에너지들이 하나의 프레임워크에 융합되어 거대한, 새로운 힘을 만들어 내는 것이다. 이 개념은 사실은 그다지 생경한 것도 아니다.
웹 2.0에서의 매쉬업(mash-up)이나 시너지 효과도 같은 측면을 갖고 있다. ‘애플리케이션+프레임워크’의 관계에선 두 개 이상의 조합이 가능하지만, 프레임워크 내부에선 그것과 비교할 수 없을 만큼의 많은 서브 프레임워크들의 조합으로 구성된다. 즉, 그 만큼의 상호작용으로 이머전스가 이뤄진다는 것이다.
실제로 이런 프레임워크를 다운로드 받아 lib 폴더를 열었을 때 상당히 많은 jar 파일들을 볼 수 있을 것이다. 이머전스란 구성 요소에 없는 특성이나 행동이 상위계층(전체구조)에서 돌연히 출연하는 현상을 말한다.
n개의 에너지들이 모인다면 n개의 에너지만 발휘하더라도 만족할 터인데 -병렬 프로세싱이나 분산 컴퓨팅을 생각해보라- n개 이상의 효과를 볼 수 있다는 것은 이들의 조합을 통해 시너지를 촉진할 수 있어야 하는 마법이 숨겨있다는 사실을 의미한다.
필자는 이 글을 통해 JBoss의 내부구조를 설명함으로서, 하위 프레임워크들이 조합되어 이머전스 되는 모양과, 프레임워크를 어떻게 사용해야 애플리케이션이 이머전스 할 수 있는지를 소개할 예정이다.

JBoss는 수많은 서브시스템(프레임워크)들을 통합하여 이머전스 된다. 서로 관계가 없는 프레임워크들이 통합되어 막강한 시너지를 창출하기 위해 통합을 위한 탄탄한 아키텍처가 필요하다. 서브 프레임워크들은 서로에 대해서, 그리고 JBoss에 통합될지 조차 모르는 상태이고 JBoss 또한 어떤 서브 프레임워크를 통합할지 모르고 있다.
J2EE 스펙이 바뀌거나 강력한 새로운 대안 프레임워크가 등장할 때 마다 그들을 포섭할 수 있어야 하는 탓이다. 이렇게 무엇을 사용할지, 무엇들이 조합될지 조차 알기 힘든 황당한 요구 사항을 위해 프레임워크나 컴포넌트 간에 철저히 결합도를 줄일 수 있는(decoupling) 유연한 아키텍처가 필요하다.
끝으로 JBoss는 WAS(Web Application Server) 자체의 한계인 ‘무거움(heavy weight)’을 극복해야 한다. 따라서 JBoss 기동 당시 모든 서비스와 컴포넌트를 메모리에 로딩하지 않기 위해 사용되는 시점에서 동적으로 서비스가 로딩 되어야 한다. 더불어 동적으로 서로를 인식하고 호출할 수 있어야 한다. 이렇게 이머전스를 위한 아키텍처 니즈를 정리하면 다음과 같다.
• JBoss 아키텍처는 여러 서비스, 프레임워크, 컴포넌트들이 잘 취합될 수 있는 강건성을 담보해야 한다.
• 그 것들의 결합도가 극도로 낮아야 한다.
• 가벼움(light weight)을 위해 런타임 시에 각 구성요소들이 plug & play될 수 있도록 동적 로딩, 동적 바인딩이 보장되어야 한다.
JBoss는 이런 저런 니즈를 만족하기 위해 마이크로 커널 아키텍처를 선택했다. 마이크로 커널은 최소한의 핵심적 기능만을 갖고 있다. 또한 프레임워크가 사용하는 서비스(혹은 서브 프레임워크)들의 컨테이너 역할을 하고 있다(<그림 1> 참조).
즉, 마이크로 커널은 이들의 라이프 사이클을 관리하고 이들 간의 동적인 관계를 맺어주기 위한 버스 역할을 한다. 가령 jBPM이 하이버네이트를 사용할 경우 이 둘 간의 관계가 하드 코딩된 강결합으로 이루어지는 것이 아니라 마이크로 커널을 통해 저장하는 ‘어떤 서비스(실제로는 하이버네이트)’에게 요청한다.
무엇보다 동적으로 구성 요소들이 추가(등록), 제거, 재등록, 바인딩(호출)되어 경량의 메모리를 사용할 수 있다.

마이크로 커널 아키텍처는 말 그대로 아키텍처일 뿐이다. 다시 말해 실체가 없는 개념적인 ‘전략’이다. 마이크로 커널을 무엇으로 어떻게 구현해야 할까? JBoss가 선택한 실체적인 ‘전술’은 JMX(Java Management Extensions)를 이용하는 것이다.
마이크로 커널은 MBean 서버가 되고 그것에 등록, 관리되는 서브 프레임워크들은 MBean 클라이언트가 된다. JMX를 사용함으로써 JMX의 장점들이 마이크로 커널에 그대로 적용된다. 따라서 마이크로 커널에 등록된 서브 프레임워크들은 이제 JMX 스펙에 의해 실시간으로 모니터링과 컨트롤 할 수 있다.


독자가 JavaEE 서버의 디자이너라고 생각해보자. 수많은 서비스와 컴포넌트를 조합하고 일부는 변경되며 또 일부는 제거되어야 한다. 왜냐하면 JavaEE 스펙은 매우 급진적으로 변했기 때문이다. 또한 서비스와 서비스, 컴포넌트와 서비스, 컴포넌트와 컴포넌트 사이의 관계들을 동적으로 관리하기란 만만한 작업이 아니다.
JavaEE 서버는 내부적 변경이 유연해야 하는 시스템이어야 한다. 이런 목적을 위해 마이크로 커널이란 토대가 만들어졌다. 하지만 JBoss는 오픈소스 프레임워크들의 집합체이다. 각각의 오픈소스들은 애초에 JBoss를 겨냥하여 만들어지지 않았기 때문에 등록된 서비스들을 유연하고 동적이며 단순하게 연결시킬 수 있는 ‘수단’이 필요하다.
이번에는 독자가 JavaEE 서버의 애플리케이션 개발자라고 생각해보자. 기존 JavaEE 방식의 컴포넌트가 서비스를 등록/삭제/변경하는 방식은 상당히 불편하다. 표준에 의해 지난하고도 장황한 설정과 연결 작업들을 해줘야 하는 탓이다. 어떤 경우는 비즈니스 로직 코드량보다 보안, 트랜잭션, 로깅 등의 서비스를 사용하기 위한 코드 량이 더 많은 경우가 있다.
하지만 비즈니스 컴포넌트의 역할은 비즈니스 로직을 수행하기 위한 목적에 충실하기만 하면 된다. 반면 JavaEE 컴포넌트들은 본래의 역할과 무관한 서비스를 다루는 역할들을 많이 포함하고 있다. 비즈니스 컴포넌트와 JavaEE 서비스들을 유연하게 분리시킬 수 있는 ‘수단’이 필요하다.

JBoss는 JGroups를 통해 클러스터링 그룹 안에 다른 서버들과 SFSB(Stateful Session Bean)의 상태를 공유한다. 앞서 설명한 예에서처럼 사용자의 로그인 정보, 주문도서 목록 정보 등의 세션 정보를 다른 서버에게 복제하여, 하나의 서버에 장애가 발생할 경우 다른 서버가 같은 상태로 서비스 할 수 있다.
이와 같이 JGroups는 JBoss 서버들 사이에 메시지 버스 역할을 담당하며 상당히 유용한 클러스터링 기반 구조를 제공한다.
물론, JGroups는 자체만으로도 사용하기 유용한 그룹 메시징 프레임워크이다. 가령 채팅 프로그램을 만든다고 가정하자. 이때 각 채팅방을 하나의 그룹으로 정의하고 그 그룹에 등록된 사용자에게 메시지를 멀티 캐스팅할 때 단순한 코딩으로 복잡한 처리를 수행하게 한다. <리스트 1>을 살펴보자.
기존의 네트워크 프로그램에서 상상하기 힘들 정도로 압축된 코드 량으로 강력한 기능을 제공한 다는 사실을 확인할 수 있다.


|