6장. JBoss EAP 6 모듈 아키텍처

Name

Date

Reason For Changes

Version

오픈나루

2013/11

Initial Version

1.0

전준식, jjeon@opennaru.com

2018/02

Second Version

2.0

JBoss EAP 5에서는 JBoss Microcontainer를 이용한 아키텍처를 사용하고 있었다. JBoss EAP 5의 각 서비스는 POJO나 JMX MBean로 구현된 모듈로 제공되며 이것들을 Microcontainer가 로드한다. HTTP나 JMS등의 여러 가지 기능을 제공하거나 각 서비스를 유연하게 추가하거나 제거하는 것이 가능했었다.

JBoss EAP 6에서는 이 모듈화를 더욱 개선하여 JBoss Module과 MSC(Modular Service Container)로 불리는 관리 기능으로 한층 더 개선시켜 개별적으로 로드 가능한 모듈 아키텍처를 적용하였다.

각각의 모듈에 대하여 기능을 설정하는 서브시스템은 Java EE의 표준을 제공하는 모듈로 JBoss 시작시의 코어 기능을 제공하는 핵심 서브시스템(Core Subsystems), 클러스터 기능을 제공하는 것 등 여러 가지 기능을 제공하는 모듈이다. 어느 서브시스템을 이용할지는 프로파일로 불리는 서브시스템 세트를 설정 파일(statndalone.xml, domain.xml)로 정의할 수가 있다.

JBoss EAP 6의 시작시 맨 처음에 bootstrap 서비스라는 다른 서비스를 배포하는데 필요한 최소한의 서비스로 JBoss Module, MSC(Modular Service Container)와 코어 서비스인 Threads, Logging, Deployment Scanner, Remoting을 시작하고, 이후에 그 외의 서비스들을 배포하게 되었다. 쉽게 말하자면 JBoss EAP 6 자체도 서브시스템으로부터 구성되어 있기 때문에 모듈의 집합체가 곧 JBoss EAP 6라고 할 수 있다. 또한 JBoss EAP 6는 이러한 서브시스템을 관리할 수 있는 운용 관리 서비스로서 Management를 제공한다. 관리 CLI나 관리 콘솔이라고 하는 운용 관리도구는 Management에 요청을 보내 결과를 수신한다.

JBoss EAP 6의 아키텍처와 JBoss EAP 6에서 제공하는 서브시스템의 관계는 그림과 같다.

eap6-arc

그림 1. JBoss EAP 6 아키텍처

이 장에서는 JBoss EAP 6의 핵심 아키텍처라고 할 수 있는 모듈에 대해서 설명한다. 모듈은 클래스 로딩을 담당하기 때문에 클래스 로딩에 대해서도 설명하고 설정 방법을 소개한다.

06-1.클래스로더 및 모듈 소개

JBoss EAP 6에서는 배포된 애플리케이션의 클래스 패스를 제어하기 위한 새로운 모듈 형식의 클래스 로드 시스템을 사용한다. 이 시스템은 기존의 계층형 클래스 로더보다 유연하고 관리 기능이 매우 강력해졌다. 개발자가 애플리케이션에서 사용할 수 있는 클래스에 대해 상세한 제어가 가능하여 애플리케이션 서버에서 제공하는 클래스를 무시하고 자신의 클래스를 사용하도록 설정할 수도 있다.

모듈 형식의 클래스 로더는 모든 Java 클래스를 모듈이라는 논리 그룹으로 나눈다. 각 모듈은 자신의 클래스 패스에 추가된 모듈에서 다른 모듈 의존성을 정의할 수 있다. 모듈 시스템은 JBoss EAP 6에 패키지 된 모든 Java 클래스와 배포된 애플리케이션의 Java 클래스에 적용된다.

JBoss EAP 6에서 배포하는 각각 JAR 및 WAR 파일도 모듈로 취급되기 때문에 개발자는 모듈 설정과 의존성을 추가하여 애플리케이션의 클래스 패스 내용을 쉽게 제어 할 수 있다.

JBoss Modules 와 MSC

JBoss EAP 6에서는 JBoss 모듈 서비스 컨테이너(이하, MSC)가 적용되어 애플리케이션 서버의 서브시스템(EJB, 서블릿, JNDI 바인딩 등)의 각 모듈로부터 사용자 애플리케이션까지 MSC 상에서 동작하는 모듈 서비스로 구성하고 있다.

모듈 서비스가 그냥 서비스로 불리기도 한다. 모듈 서비스는 개별적으로 시작, 정지할 수 있다. 또, 모듈 서비스간에는 의존관계(dependencies)가 있어 어느 모듈 서비스에서 필요한 다른 모듈 서비스로 의존성을 정의할 수 있기 때문에 다른 모듈 서비스를 주입하는 일도 가능하다. MSC에서는 사용하려는 모듈 서비스에 관한 모든 의존성이 채워지면, 그 모듈 서비스를 시작한다. 반대로 의존성 중 1개라도 빠졌을 경우엔 해당의 모듈 서비스는 MSC에 의해 정지된다.

image

그림 2. JBoss MSC 의 코어 서비스

모듈 서비스에서 사용되는 용어들을 정리해보면 다음 표와 같다.

구분 작업

서비스 컨트롤러

서브시스템이나 모듈 등이 서비스로서 실행될 수 있도록 서비스 인터페이스를 제공하거나 서비스에 대한 제어를 담당한다.

서비스 빌더

서브시스템이 서비스를 설치하기 위해 필요한 처리를 하는 빌더 기능을 제공한다.

서비스 레지스트리

서비스 빌더를 이용해 서비스를 실행할 때 레지스트리에 서비스명과 서비스 컨트롤러를 등록한다. MSC는 이 레지스트리를 참조하여 적합한 서비스 컨트롤러를 반환하여 서비스를 제어하게 된다.

인젝터

서비스 빌더가 서비스를 실행할 때 서비스가 의존하는 모듈을 인젝션 하지만 이것도 MSC에서 수행된다. 인젝션 할 때에 필요한 기능이 인젝터(injector)이고, 의존성이 정의되어 있어야 한다. 또, 모든 서비스 인스턴스로 접근은 Value 인터페이스에 의해 정의되고 있다.

Concurrent 서비스 컨테이너

모든 서비스를 제어하는 기반이 되는 중요한 컴포넌트이다. 이 컨테이너는 서비스를 시작하기 위해 필요한 작업을 태스크화하여 그 태스크를 멀티 스레드로 처리하고 있다. JBoss를 시작하는데 필요한 bootstrap 처리 등도 리스너 태스크로서 등록해 처리한다.

표 1. 모듈의 주요 용어

06-2.모듈

모듈은 클래스 로드 및 의존성 관리를 위해 사용되는 클래스의 논리적 그룹이다. 모듈은 필요할 때만 로드 된다. 일반적으로 명시적, 암시적 의존성이 있는 애플리케이션이 배포될 경우에만 실행된다.

JBoss EAP 6에서 모듈을 다음과 같이 정의할 수 있다.

  • 클래스를 로드할 때 묶음 단위

  • 일반적으로 하나의 jar 파일

  • 여러 개의 jar파일이나 프로퍼티 파일 등 자원을 포함할 수 있음

  • 모듈 하나에 대해서 하나의 클래스 로더

  • 각 모듈은 런타임에 필요한 의존 모듈을 정의

  • 계층형 클래스 로더 구조가 아닌 그래프 클래스 로더 구조

  • ‘클래스 패스’는 없음

JBoss EAP 6에는 정적 모듈(Static module)과 다이내믹 모듈(Dynamic Module)의 두 가지 모듈이 있다. 이 두 가지 모듈의 차이점은 패키징 방법이 다를 뿐이며, 모든 모듈은 동일한 기능을 갖는다.

구분 설명

정적 모듈

(Module 디렉터리에 저장 방식)

정적 모듈은 애플리케이션 서버 $JBOSS_HOME/modules/ 디렉터리에 저장되어 배포되었다. 각 하위 디렉터리는 하나의 모듈이고 1 개 또는 여러 개의 JAR 파일 및 설정 파일인 modules.xml가 저장되었다. 모듈의 이름은 module.xml 파일에 정의된다. JBoss EAP 6에서 제공하는 모든 API(Java EE API 및 JBoss Logging과 같은 API 포함)는 정적인 모듈로 제공된다.

<?xml version="1.0" encoding="UTF-8"?>

<module xmlns="urn:jboss:module:1.0" name="com.mysql">

  <resources>

    <resource-root path="mysql-connector-java-5.1.15.jar"/>

  </resources>

  <dependencies>

    <module name="javax.api"/>

    <module name="javax.transaction.api"/>

  </dependencies>

</module>

별도의 외부 라이브러리를 사용하기 위하여 사용자가 직접 지정한 정적 모듈도 서버에 배포할 수 있다. 이러한 라이브러리들은 JBoss 관리자가 라이브러리가 포함된 모듈을 만들어 설치할 수 있다. 사용자 지정 정적 모듈에서도 명시적으로 의존성을 선언할 수 있다.

다이내믹 모듈

(배포 방식 모듈)

다이내믹 모듈은 JAR 또는 WAR 배포(또는 EAR의 하위 배포)시 JBoss EAP 6에서 생성되어 로드된다. 다이내믹 모듈의 이름은 배포 된 파일의 이름이다. 배포되는 애플리케이션도 다른 모듈과 마찬가지로 로드되기 때문에 의존성을 설정할 수 있고 다른 모듈을 참조하여 사용할 수 있다.

표 2. 정적 모듈과 다이내믹 모듈의 차이

모듈 의존성

모듈 의존성은 모듈이 동작하기 위해 다른 모듈의 클래스가 필요한 경우에 이를 참조하기 위한 선언이다. 명시적으로 다른 모듈의 종속성을 지정하지 않으면 의존성은 전혀 없다. 모듈은 얼마든지 다른 모듈의 의존성을 선언할 수 있다. JBoss EAP 6에서 모듈을 로드 할 때 모듈 클래스 로더가 모듈의 의존성을 분석하고 각 의존성 클래스를 클래스 패스에 추가한다. 지정된 의존성 모듈이 없으면 모듈을 로드 할 수 없어 오류가 발생한다.

배포된 애플리케이션(JAR 및 WAR)은 다이내믹 모듈로 로드 된 의존성을 사용하여 JBoss EAP 6에서 제공하는 API에 액세스한다.

의존성은 두 가지 유형으로 명시적, 암시적 의존성이 있다.

명시적 의존성 관계는 개발자가 설정 파일에서 선언할 수 있다. 정적 모듈 의존성을 modules.xml 파일에 선언할 수 있다. 다이내믹 모듈은 배포의 MANIFEST.MF 또는 jboss-deployment-structure.xml 디스크립터에 의존성을 선언할 수 있다.

명시적 의존성은 선택적(optional)으로 지정할 수 있다. 선택적인 의존성이 로드되지 못한다고 해서 모듈을 로드하는데 실패하지는 않는다. 그러나 이후에 의존성을 정의해도 그것이 모듈의 클래스 패스에 추가되지 않는다. 즉 모듈이 로드 될 때 종속성 모듈을 사용할 수 있어야 한다.

암시적 의존성은 특정 조건 또는 메타 데이터를 발견하면 JBossEAP 6에서 자동으로 추가한다. JBoss EAP 6와 함께 제공되는 Java EE 6 API는 배포시 암시적 의존성이 감지되어 추가된 모듈의 대표적인 예이다.

설정을 통하여 원치 않는 암시적 의존성을 제외 할 수도 있다. jboss-deployment-structure.xml 디스크립터 파일에 <exclusions>를 사용하여 정의하면 된다. 또, JBoss EAP 6에서 암시적 의존성을 추가하려면 WEB-INF/lib 디렉터리에 필요한 JAR파일을 넣는 방법을 일반적으로 사용한다.

모듈의 클래스 패스는 자신의 클래스와 직접적인 의존성을 갖는 것만 포함한다.

모듈은 해당 의존성 중 하나의 의존성 클래스에만 접근할 수 있다. 하지만 모듈은 특정 명시적 의존성을 익스포트 할 수 있다.

모듈 의존성 예

모듈 A는 모듈 B 에 의존하고, 모듈 B는 모듈 C 에 의존한다. 모듈 A는 모듈 B의 클래스에 접근할 수 있고 모듈 B는 모듈 C 의 클래스에 접근할 수 있다 .하지만 모듈 A는 모듈 C의 클래스는 접근할 수 없다. 다음과 같은 방법을 사용하면 모듈 A에서 모듈 C의 클래스에 접근할 수 있다.

  1. 모듈 A 에서 모듈C에 대한 명시적 의존성을 정의한다.

  2. 모듈 B에서 모듈 C에 대한 의존성을 익스포트한다.

image

06-3.배포 시 클래스로딩

클래스 로더의 이해

클래스 로더는 그 이름에서 알 수 있듯이 클래스를 로드하는 것이다. 대개의 자바 개발자는 특별히 의식하지 않고 클래스를 사용하고 있지만, 클래스는 사용되기 전에 반드시 클래스 로더를 통해 JVM(Java Virtual Machine)의 메모리 영역에 로드한된다. 올바른 Java EE 패키징을 위해서는 클래스 로더에 대한 지식이 필수적이다.

클래스 로더를 이해하는 데 가장 중요한 개념은 ‘위임 모델’이다. 아래의 그림에서 자바 가상 머신의 클래스 로더 구조를 살펴보자.

image

그림 3. Java VM의 클래스 로더

클래스 로더는 필요시 부모 클래스 로더에 클래스의 로드를 부탁하는 구조, 즉 맡기는(위임) 것이다. 예를 들어, 시스템 클래스 로더가 클래스를 로드하려고 할 때 시스템 클래스 로더는 자신의 로컬 클래스 패스, 즉 환경변수 CLASSPATH에서 찾기 전에 먼저 부모인 확장 클래스 로더에 클래스의 로드를 요청하게 된다. 마찬가지로 확장 클래스 로더도 먼저 부모 클래스 로더인 부트 스트랩 클래스 로더에 클래스의 로드를 위임하게 된다. 부모 클래스 로더에서 클래스가 발견된 경우에 거기서 클래스를 로딩하여 종료하게 된다. 부모에 클래스가 없을 때 비로소 자신의 로컬 클래스 패스를 찾게 되고 클래스를 로드하게 된다. 위임 모델에서 중요한 것은 자식이 먼저하는 것이 아니라 먼저 부모에게 위임하는 것이다.

배포시 클래스 로딩

클래스 로딩을 위해 JBoss EAP에서 배포는 모두 모듈로 처리된다. 이러한 배포 형식의 모듈을 다이내믹 모듈이라고 한다. 클래스 로딩의 작동 방식은 배포 유형에 따라 다르다.

배포 방식 설명

WAR 패키지

WAR 패키지가 하나의 모듈로 간주된다. WEB-INF/lib 디렉터리의 파일들은 WEB-INF/classes 디렉터리에 있는 클래스와 동일하게 처리된다. WAR로 패키지 된 클래스들은 동일한 클래스 로더에 로드된다.

EAR 패키지

EAR 배포는 여러 개의 모듈로 구성된다. 이 모듈은 다음 규칙에 따라 정의된다.

  • EAR의 lib/ 디렉터리는 부모 모듈이다.

  • 또 EAR의 각 WAR 배포는 하나의 모듈이다.

  • 마찬가지로 EAR 내의 EJB JAR 배포도 하나의 모듈이다.

EAR의 WAR, JAR 배포와 같은 서브 배포 모듈은 자동으로 부모 모듈에 의존하지만 하위 배포끼리 자동으로 의존성을 갖지는 않는다. 이것은 하위 배포 단절(subdeployment isolation)이라고 한다.

서브 배포 모듈 간의 명시적 종속 관계는 다른 모듈과 같은 방법으로 추가 할 수 있다.

표 3. WAR 패키지와 EAR 패키지의 동작 방식

클래스로딩의 우선순위

JBoss EAP 6 모듈 클래스 로더는 우선순위 구조를 이용하여 클래스 로딩 충돌이 발생하지 않도록 한다.

배포시 패키지와 클래스들의 리스트는 각각의 배포와 해당 종속성에 의해 생성된다. 이 목록은 클래스 로딩의 우선순위 규칙에 따라 순서대로 나열된다. 런타임에 클래스를 로드하면 클래스 로더는이 목록을 검색하여 최초로 일치하는 것을 로드한다. 이렇게 하면 배포 클래스 경로에 동일한 클래스나 패키지의 여러 복사본이 충돌하지 않게 된다.

클래스 로더는 위에서 아래로(내림차순) 클래스를 로드 한다.

우선순위 의존성 분류 설명

image222

  1. 암시적 의존성

Java EE API 들은 JBoss EAP 6가 자동으로 추가한 의존성이다. 이 의존성은 일반적인 기능 및 JBoss EAP 6의 API가 포함되어 있기 때문에 우선순위가 가장 높다.

  1. 명시적 의존성

애플리케이션 설정에서 수동으로 추가되는 의존성이다. 이러한 의존성은 애플리케이션의 MANIFEST.MF 파일이나 새로운 옵션으로 추가된 JBoss 배포 디스크립터 jboss-deployment-structure.xml 파일을 사용하여 추가 가능하다.

  1. 로컬 리소스

배포 애플리케이션 내에 패키지된 클래스 파일.

예를 들면 WAR 파일의 WEB-INF/classes나 WEB-INF/lib 디렉터리의 JAR 파일들

  1. 배포 간의 의존성

EAR 배포 애플리케이션에 있는 다른 배포와의 의존성. 여기에는 EAR의 lib 디렉터리에 있는 클래스 나 다른 EJB jar에 정의된 클래스가 포함될 수 있다.

표 4. 클래스 로딩의 우선순위

EAR 배포와 클래스로딩

엔터프라이즈 아카이브(EAR)는 JAR 또는 WAR 배포와 같이 단일 모듈로 로드하지 않고, 독립적인 여러 모듈로 로드한다.

다음과 같은 규칙으로 EAR의 모듈이 로드된다.

  • 각 WAR 및 EJB JAR subdeployments는 모듈이다.

  • EAR 아카이브 루트에 있는 lib/ 디렉터리의 내용은 모듈이다. 이것을 부모 모듈이라고 한다.

  • 모듈은 다른 모듈과 같이 암시적 의존성이 있다.

  • WAR의 subdeployments는 상위 모듈 및 EJB JAR 파일의 subdeployments에 암시적 종속성이 있다.

  • EJB JAR의 subdeployments는 상위 모듈과 다른 EJB JAR 파일의 subdeployments에 암시적 종속성이 있다.

다른 모듈과 마찬가지로 subdeployment는 다른 subdeployment에 대해 명시적 종속 관계를 설정할 수 있다.

설정 방법은 다음과 같다. 기본값은 false이다.

<subsystem xmlns="urn:jboss:domain:ee:1.1">
  <ear-subdeployments-isolated>true</ear-subdeployments-isolated>
  <spec-descriptor-property-replacement>false</spec-descriptor-property-replacement>
  <jboss-descriptor-property-replacement>true</jboss-descriptor-property-replacement>
</subsystem>

JBoss EAP 6는 기본적으로 subdeployment는 클래스 로더 분리(isolation)를 하지 않아서 암시적 의존성이 있다. 간단히 말하면 EAR에 있는 WAR와 EJB JAR들은 서로 참조할 수 있다. 하지만 Java EE 스펙에서는 서로 참조하지 못하도록 규정하고 있다. 엄격한 Java EE 호환성이 필요한 경우에 설정을 변경하여 사용한다. Java EE 6 표준에서는 포터블 애플리케이션 종속성을 명시적으로 각 subdeployment의 MANIFEST.MF 파일에서 클래스 패스로 선언하지 않는 한 서로 액세스 할 수 있는 subdeployments에 의존하지 않도록 규정하고 있다.

일반적으로 서로 참조하도록 구성하는 경우가 많아, 기본 옵션을 그대로 사용한다.

다이내믹 모듈의 모듈 이름

모든 모듈은 JBoss EAP 6가 모듈로 로드한 다음과 같은 규칙에 따라 이름이 지정된다.

배포 방식 설명

WAR 패키지의 모듈 이름 지정

deployment.DEPLOYMENT_NAME

예를 들어, inventory.war 와 store.jar 파일을 배포하게 되면 모듈의 이름은 deployment.inventory.war 과 deployment.store.jar가 된다.

EAR 패키지의 모듈 이름 지정

deployment.EAR_NAME.SUBDEPLOYMENT_NAME

예를 들어, accounts.ear 에 있는 reports.war 하위 배포 모듈 이름은 deployment.accounting.ear.reports.war 이 된다.

표 5. 다이내믹 모듈의 모듈 이름 지정

jboss-deployment-structure.xml 파일

jboss-deployment-structure.xml는 JBoss EAP 6의 새로운 배포 디스크립터이다. 이 배포 디스크립터는 배포 시 클래스 로딩을 제어할 수 있도록 한다.

이 배포 디스크립터 XML 스키마는 $JBOSS_HOME/docs/schema/jboss-deployment-structure-1_0.xsd 에 있다.

06-4.다이내믹 모듈(배포 모듈)에 명시적 의존성 추가하기

다이내믹 모듈은 배포의 MANIFEST.MF 또는 jboss-deployment-structure.xml 디스크립터에 의존성을 선언할 수 있다. 애플리케이션에 명시적 의존성을 추가하는 방법을 설명한다. 명시적인 모듈 의존성을 애플리케이션에 추가하면 이 모듈의 클래스를 애플리케이션의 클래스 패스에 추가 할 수 있다.

의존성을 설정하는 방법은 두 가지가 있다.

  1. 배포 애플리케이션의 MANIFEST.MF 파일에 항목을 추가한다.

  2. jboss-deployment-structure.xml 배포 디스크립터에 항목을 추가한다.

MANIFEST.MF 의존성 추가 방법

MANIFEST.MF 파일에 필요한 의존성 항목을 만들 수 있다.

따라하기

  1. MANIFEST.MF 파일 추가

  2. 의존성 항목 추가

  1. MANIFEST.MF 파일 추가

    프로젝트에 MANIFEST.MF 파일이 없으면 MANIFEST.MF 라는 파일을 만든다. 웹 애플리케이션(WAR)에서 이 파일을 WEB-INF 디렉터리에 추가한다. EJB 아카이브(JAR)는 META-INF 디렉터리에 추가한다.

  1. 의존성 항목 추가
    의존성 모듈 이름을 쉼표로 구분하여 의존성 항목을 MANIFEST.MF 파일에 추가한다.
    Dependencies : org.javassist, org.apache.velocity

    • 옵션 : 의존성을 선택한다
      의존성 항목 모듈로 optional 을 지정하면 의존성을 옵션으로 할 수 있다.
      Dependencies : org.javassist optional, org.apache.velocity

    • 옵션 : 의존성 익스포트
      의존성 항목 모듈로 export 를 지정하면 의존성을 내보낼 수 있다.
      Dependencies: org.javassist, org.apache.velocity export

jboss-deployment-structure.xml 의존성 추가 방법

jboss-deployment-structure.xml 배포 디스크립터는 클래스 로딩을 제어 할 수 있는 새로운 디스크립터이다. 이 디스크립터는 배포 애플리케이션의 META-INF/디렉터리 또는 WEB-INF/디렉터리에 있으면 된다. 암시적 의존성 모듈이 추가되지 않도록 하는 기능, 추가되지 않은 의존성을 추가하는 기능, 추가 모듈의 정의, EAR의 클래스 로딩의 동작 변경, 모듈에 리소스 경로를 추가하는 기능 등 다양한 기능이 있다.

배포 디스크립터파일의 의존성을 추가하면 JBoss EAP 6에서 애플리케이션 배포시 지정된 모듈의 JAR 파일들을 애플리케이션의 클래스 패스에 클래스를 추가한다.

다음은 jboss-deployment-structure.xml 의존성 추가 방법이다,

따라해보기

  1. jboss-deployment-structure.xml 추가

  2. 의존성 섹션 추가

  3. 모듈 요소 추가

  1. MANIFEST.MF 파일 추가

    애플리케이션에 jboss-deployment-structure.xml 라는 새 파일을 만들어 프로젝트에 추가한다. 이 파일은 <jboss-deployment-structure> 이 루트인 XML 파일이다.

    <jboss-deployment-structure>
    
    </jboss-deployment-structure>

    웹 애플리케이션(WAR)에서는 이 파일을 WEB-INF 에 추가하고, EJB 아카이브(JAR)은 META-INF 디렉터리에 추가한다.

  1. 의존성 섹션 추가
    <deployment>를 문서 루트에 생성하고 그 안에 <dependencies> 엘리먼트를 만든다.

  1. 모듈 요소 추가
    의존성 노드에 각 모듈 의존성에 대한 모듈 엘리먼트를 추가한다. name 에 모듈의 이름으로 지정한다.

    <module name="org.javassist" />
    • 옵션 : 의존성을 선택한다
      모듈에 optional 속성을 추가하면 의존성을 옵션으로 지정할 수 있다. 이 속성의 기본값은 FALSE 이다.

      <module name="org.javassist" optional="TRUE" />
    • 옵션 : 의존성 익스포트
      모듈에 export속성을 추가하면 의존성을 의존성을 사용하는 모듈에서도 사용할 수 있도록 한다. 이 속성의 기본값은 FALSE 이다.
      다음이 완성된 XML 설정파일이다.

      <?xml version="1.0" encoding="UTF-8"?>
      <jboss-deployment-structure>
        <deployment>
          <dependencies>
            <module name="org.javassist" />
            <module name="org.apache.velocity" export="TRUE" />
          </dependencies>
        </deployment>
      </jboss-deployment-structure>

모듈이 암시적으로 로드되지 않도록 설정

다음에서는 모듈 의존성 목록에서 제외하도록 애플리케이션을 설정하는 방법을 설명한다.

배포 가능한 애플리케이션을 설정하여 암시적 의존성으로 로드되지 않도록 할 수 있다. 이것은 JBoss EAP 6에서 제공되는 암시적 의존성은 일반적으로 다른 버전의 라이브러리를 사용하거나 프레임 워크가 애플리케이션에 포함되는 경우 사용한다.

따라해보기

  1. jboss-deployment-structure.xml 작성

  2. <exclusions> 엘리먼트 작성

  3. exclusions 요소에 제외 모듈 등록

  1. jboss-deployment-structure.xml 작성
    애플리케이션에 jboss-deployment-structure.xml 라는 새 파일을 만들어 프로젝트에 추가한다. 이 파일은 <jboss-deployment-structure> 이 루트인 XML 파일이다.

    <jboss-deployment-structure>
    </jboss-deployment-structure>

    웹 애플리케이션(WAR)에서이 파일을 WEB-INF 에 추가하고, EJB 아카이브 (JAR)은 META-INF 디렉터리에 추가한다.

  1. <exclusions> 엘리먼트 작성
    <deployment>를 문서 루트에 생성하고 그 안에 <exclusions>를 만든다.

    <deployment>
      <exclusions>
      </exclusions>
    </deployment>
  1. exclusions 요소에 제외 모듈 등록
    exclusions 에 제외할 각 모듈에 대해 `<module>`을 추가한다. name에 제외할 모듈의 이름으로 설정한다.

    <module name="org.javassist" />

    다음이 완성된 설정파일이다.

    <?xml version="1.0" encoding="UTF-8"?>
    <jboss-deployment-structure>
      <deployment>
        <exclusions>
          <module name="org.javassist" />
          <module name="org.dom4j" />
        </exclusions>
      </deployment>
    </jboss-deployment-structure>

배포시 서브시스템을 제외하도록 설정

배포 시에 서브 시스템을 제외시키기 위해 필요한 단계에 대해 설명한다. 이 작업은 jboss-deployment-structure.xml 설정 파일을 편집한다. 서브시스템을 제외하는 것은 서브시스템을 제거하는 것과 같은 효과가 있지만, 하나의 배포파일에만 적용된다.

따라해보기

  1. jboss-deployment-structure.xml 편집

  2. <exclusions> 엘리먼트 작성

  1. jboss-deployment-structure.xml 편집
    텍스트 편집기에서 jboss-deployment-structure.xml 파일을 연다.

  1. <exclusions> 엘리먼트 작성
    <deployment> 태그 안에 다음과 같은 추가한다.

    <exclude-subsystems>
      <subsystem name="SUBSYSTEM_NAME" />
    </exclude-subsystems>

파일을 저장한다.

위와 같이 설정하면 애플리케이션 배포시 서브 시스템이 제외된다. 서브시스템 배포시 더 이상 실행되지 않게 된다.

다음은 앞서 설명한 내용들이 들어 있는 jboss-deployment-structure.xml파일이다.

<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
  <ear-subdeployments-isolated>true</ear-subdeployments-isolated>
  <deployment>
    <exclude-subsystems>
      <subsystem name="resteasy"/>
    </exclude-subsystems>
    <exclusions>
      <module name="org.javassist"/>
    </exclusions>
    <dependencies>
      <module name="deployment.javassist.proxy"/>
      <module name="deployment.myjavassist"/>
      <module name="myservicemodule" services="import"/>
    </dependencies>
    <resources>
      <resource-root path="my-library.jar"/>
    </resources>
  </deployment>
  <sub-deployment name="myapp.war">
    <dependencies>
      <module name="deployment.myear.ear.myejbjar.jar"/>
    </dependencies>
    <local-last value="true"/>
  </sub-deployment>
  <module name="deployment.myjavassist">
    <resources>
      <resource-root path="javassist.jar">
        <filter>
          <exclude path="javassist/util/proxy"/>
        </filter>
      </resource-root>
    </resources>
  </module>
  <module name="deployment.javassist.proxy">
    <dependencies>
      <module name="org.javassist">
        <imports>
          <include path="javassist/util/proxy"/>
          <exclude path="/**"/>
        </imports>
      </module>
    </dependencies>
  </module>
</jboss-deployment-structure>

06-5.모듈 서비스의 로드 방법

JBoss MSC(Modular Service Container)에서는 의존관계(dependencies)가 있는 모듈 서비스 로드에 Concurrent DAG(Directed Acyclic Graph) Execution 라는 방식을 도입하여 종래의 로드 방법(Serial DAG Execution)보다 빠르게 로드하는 것이 가능하게 되었다. 예를 들어, 다음 그림과 같은 모듈의 의존관계(dependencies) 와 같은 의존관계(dependencies)가 있는 모듈을 로드하는 경우, 종래는 다음 그림과 같이 Serial DAG Execution 와 같이 단일의 CPU 코어로 각 모듈을 차례로 로드한다.

image

그림 4. 모듈의 의존 관계

image

그림 5. Serial DAG 실행 방법

최근의 CPU는 멀티 코어가 일반적이기 때문에 단일의 CPU 코어로 처리하는 것은 그다지 효율적인 방식이 아니다. 이 때문에 JBoss EAP 6에서는 다음 그림과 같이 Concurrent DAG Execution 을 사용하여 가능하면 병렬로 모듈을 로드하여 CPU의 코어를 효율적으로 이용해 시작 시간의 단축할 수 있었다.

image

그림 . Concurrent DAG 실행 방법

06-6.JBoss EAP의 부트

JBoss EAP 6의 bootstrap 은 서비스 컨트롤러에 의해 서버 서비스의 부팅을 처리하는 일로 시작한다. 부트시 설정 파일(standalone.xml 등)을 읽어서 부팅시 사용할 오퍼레이션을 작성하고 필요한 처리를 각각 스텝으로 등록하고, 멀티 스레드로 처리한다. 서브시스템을 시작할 때, parallel-subsystem-boot 오퍼레이션을 작성해 멀티 프로세스로 서브시스템을 시작한다.

JBoss EAP 6의 부트 순서는 extension, 서브시스템, 배포 순 이다.

image

그림 7. JBoss EAP 6시작시 extension 모듈 로드 절차

JBoss EAP 6 부팅 과정에서 extension 모듈 초기화 과정을 살펴보면, 먼저 standalone.xml 파일을 파싱하여 <extension>모듈의 이름을 찾는다. extension 모듈을 $JBOSS_HOME/modules 디렉터리에서 모듈 이름에 해당하는 모듈을 로딩한다. 이 모듈은 org.jboss.as.controller.Extension을 구현한 클래스이다. 이 모듈은 어떤 XML 네임스페이스를 사용할 것인지를 구현하고 있어, 해당하는 XML 스키마를 읽어 MSC(Modular Service Container)에서 weld 서브시스템을 시작한다.

standalone.xml 파일에 정의된 서브시스템들이 모두 시작되면, 애플리케이션을 배포한다. 이런 과정으로 JBoss EAP 6가 부팅된다.