애플리케이션 클라이언트

본 장에서는 JEUS 서버와는 별도의 JVM에서 수행되는 애플리케이션 클라이언트에 대해서 설명한다.

1. 개요

일반적으로 Jakarta EE 애플리케이션을 호출하거나 Jakarta EE의 서비스를 제공받기 위해서는 JEUS의 클라이언트 컨테이너에서 구동되는 애플리케이션 클라이언트(Application Client) 모듈을 사용한다.

애플리케이션 클라이언트는 Jakarta EE 환경을 사용하는 standalone 클라이언트로 Jakarta EE 스펙에 정의되어 있는 애플리케이션 클라이언트 컨테이너(Application Client Container)에서 구동되는 애플리케이션이다. 애플리케이션 클라이언트 모듈은 JEUS 클라이언트의 한 형태이다. 이 형태는 클라이언트 또는 서버 시스템이나 테스트 및 디버깅을 하는 경우 유용하게 사용할 수 있는 클라이언트이다.

JEUS 애플리케이션 클라이언트는 클라이언트 컨테이너를 사용해서 Naming Service, Scheduler, Security 등과 같은 JEUS 서비스를 사용할 수 있다. 클라이언트 컨테이너를 사용하지 않더라도 JEUS 클라이언트 라이브러리를 사용하면 JNDI, Security 등의 일부 서비스를 사용할 수는 있지만 Dependency Injection, JEUS Scheduler 등에 해당하는 서비스는 사용할 수 없다.

  1. Jakarta EE 기반의 애플리케이션 클라이언트의 자세한 내용은 Jakarta EE 스펙을 참고한다.

  2. JEUS XML 스키마의 자세한 내용은 "JEUS XML Reference"의 "jeus-client-dd.xml"을 참고한다.

2. 프로그램 작성

본 절에서는 JEUS 클라이언트와 서버 환경의 아키텍처에 대해 알아보고, 간단한 샘플 코드를 예로 들어 설명한다.

2.1. 프로그램 구조

애플리케이션 클라이언트는 서버와는 다른 JVM에서 실행되는 클라이언트 프로그램이다.

애플리케이션 클라이언트는 main() 메소드를 호출해서 실행하고, 가상 머신이 종료되면 실행을 마친다. 다른 Jakarta EE 애플리케이션 컴포넌트처럼 애플리케이션 클라이언트는 시스템 서비스를 제공하는 클라이언트 컨테이너에서 동작한다. 클라이언트 컨테이너는 다른 Jakarta EE 컨테이너에 비해서 적은 양의 시스템 리소스를 사용한다. 클라이언트 컨테이너는 일반 애플리케이션 클라이언트에서 JEUS가 제공하는 Jakarta EE 서비스를 사용할 수 있는 환경을 제공한다.

이 서비스에는 JNDI, Scheduler, Security 그리고 JNDI 서비스를 통해서 JEUS에 바인딩되어 있는 애플리케이션 컴포넌트(EJB) 및 시스템 리소스들(JDBC DataSource, JMS Connection Factory 등)에 대한 사용이 포함된다.

figure client architecture
애플리케이션 클라이언트 아키텍처

2.2. 예제

애플리케이션 클라이언트는 일반적인 Java 프로그램과 마찬가지로 반드시 public으로 선언된 main() 메소드를 가지고 있어야 한다.

다음 예제는 Injection을 통해 EJB를 호출한다(JEUS_HOME/samples/client/hello/hello-client 예제를 참고).

애플리케이션 클라이언트 : <HelloClient.java>
package helloejb;

import java.io.*;
import jakarta.ejb.EJB;

public class HelloClient {
    @EJB(mappedName="helloejb.Hello")
    private static Hello hello;

    public static void main(String[] args) {
        System.out.println("EJB output : " + hello.sayHello());
    }
}

3. Deployment Descriptor(DD)

본 절에서는 Deployment Descriptor(이하 DD)를 작성하고 생성하는 방법에 대해 설명한다.

3.1. DD 작성

DD 작성 방법은 다음과 같이 2가지로 나누어진다.

  • Jakarta EE DD

    Jakarta EE 스펙에서는 클라이언트 모듈에 대한 DD를 정의하고 있는데, 이는 Web Application Server(WAS)에 관계없이 표준적인 설정을 담고 있다.

    표준 DD 파일 대신, Annotation을 통해 설정할 수 있다. 따라서 위의 애플리케이션 클라이언트 : <HelloClient.java>도 별도의 application-client.xml이 없이도 동작한다.

    표준 XML Descriptor에 대한 자세한 설명은 Jakarta EE 스펙을 참고한다.

  • JEUS DD

    서버와 애플리케이션 클라이언트가 통신할 때 클라이언트 모듈에 대한 정보가 필요한데, DD는 이러한 정보들을 가지고 있는 XML 설정이다.

    클라이언트를 위한 DD는 META-INF\jeus-client-dd.xml이다. DD를 사용하여 각각의 애플리케이션 클라이언트를 클라이언트 컨테이너에 디플로이할 때에 어떤 서비스를 사용할지 결정할 수 있다. 또한 실행하는 경우에도 프로그램의 별도의 수정 없이 DD만 수정하여 해당하는 애플리케이션 클라이언트에게 적용할 수 있다.

    일반적으로 클라이언트가 사용하는 리소스 등을 지정하기 위해 사용하는데, 위의 애플리케이션 클라이언트 : <HelloClient.java>에 대해서는 이 DD를 사용하지 않아도 되므로 생략한다.

jeus-client-dd.xml에 대한 자세한 설명은 "JEUS XML Reference"를 참고한다.

3.2. DD 생성

DD를 생성할 때 필요하다면 JEUS에서 클라이언트 모듈을 디플로이하기 전에 jeus-client-dd.xml 파일을 작성한다.

다음은 DD를 작성한 XML 파일의 예이다.

XML에서 클라이언트가 사용하는 환경변수, EJB 애플리케이션이 바인딩된 이름, 바인딩된 JDBC DataSource의 이름, JMS Queue의 JNDI 바인딩 이름을 지정하고 있다. 환경변수를 제외하고는 application-client.xml의 <ref-name>에 실제 바인딩된 JNDI 이름을 <export-name>으로 지정한다.

DD 생성 : <jeus-client-dd.xml>
<jeus-client-dd>
    <env>
        <name>year</name>
        <type>java.lang.Integer</type>
        <value>2002</value>
    </env>
    <ejb-ref>
        <jndi-info>
            <ref-name>count</ref-name>
            <export-name>count_bean</export-name>
        </jndi-info>
    </ejb-ref>
    <res-ref>
        <jndi-info>
            <ref-name>datasource</ref-name>
            <export-name>Oracle_DataSource</export-name>
        </jndi-info>
    </res-ref>
    <res-env-ref>
        <jndi-info>
            <ref-name>jms/SalaryInfo</ref-name>
            <export-name>jms/salary_info_queue1</export-name>
        </jndi-info>
    </res-env-ref>
</jeus-client-dd>

jeus-client-dd.xml 파일의 각 element에 대한 설명은 "JEUS XML Reference"를 참고한다.

4. 패키징

클라이언트 모듈의 패키징 방식은 수동 패키징 방식과 IDE를 사용한 패키징 방식으로 나눠진다.

  • 수동 패키징

    필요하다면 사용자의 컴퓨터에 설치되어 있는 텍스트 에디터나 XML 에디터를 사용해서 DD XML 파일을 생성하고, 필요한 파일을 모아서 Java에서 제공하는 JAR 툴을 사용하여 클라이언트 모듈에 대한 JAR 파일을 생성한다.

    애플리케이션 클라이언트를 패키징하려면 애플리케이션을 구성하고 있는 클래스 파일과 필요하다면 application-client.xml, jeus-client-dd.xml 파일이 포함되어 있어야 한다.

    콘솔에서는 jar 명령어를 사용하여 클라이언트 모듈에 대한 JAR 파일을 생성한다. 표준에서는 JAR 파일의 MANIFEST.MF에 Main-Class 속성으로 이 JAR 파일이 실행될 때 사용할 메인 클래스를 지정할 수 있다. 이 경우 JEUS 클라이언트 컨테이너는 메인 클래스를 알려주지 않아도 자동으로 이 클래스를 실행한다.

    다음은 jar 명령어를 사용하여 JAR 파일을 생성하는 예이다.

    jar cvf hello-client.jar *
  • IDE를 사용한 패키징

    Eclipse나 NetBeans, IntelliJ IDEA와 같이 Jakarta EE 환경을 지원하는 IDE 툴에서 생성한다. 이 방법은 각 IDE의 도움말을 참고한다.

5. Deploy

애플리케이션 클라이언트 모듈은 수동으로 직접 deploy를 진행한다.

모듈에는 필요에 따라 Jakarta EE 표준 DD 파일인 application-client.xml과 JEUS에서 제공하는 jeus-client-dd.xml이 있다. 애플리케이션 클라이언트에 대한 모듈 파일을 생성한 후 해당 파일을 원하는 위치로 이동한다.

만약 웹 서비스 클라이언트로 동작하는 기능이 있다면 추가로 콘솔 툴(jeusadmin)을 통해 deploy하거나 appcompiler 명령어를 사용해야 웹 서비스 Stub이 생성된다.

Deploy에 대한 자세한 내용은 JEUS Applications & Deployment 안내서를 참고한다.

6. 실행

본 절에서는 각 서비스별로 추가적으로 필요한 JEUS 라이브러리와 콘솔에서 모듈을 실행하는 방법에 대해 설명한다.

6.1. JEUS 라이브러리

애플리케이션 클라이언트로 웹 서비스를 사용할 경우 라이브러리 실행 단계에서 기본 라이브러리인 JEUS_HOME/lib/client/clientcontainer.jar 외에 추가적으로 필요한 라이브러리들이 존재한다. 이들은 대부분 JEUS_HOME/lib/system(이하 SYSTEM_LIB_DIR) 아래에 위치한다.

다음은 서비스별 추가적으로 필요한 JEUS 라이브러리 목록이다.

서비스 JEUS 라이브러리

JMS(Java Message Service)

  • SYSTEM_LIB_DIR/jms.jar

Web Service

  • SYSTEM_LIB_DIR/jakarta.mail-2.0.1.jar

  • JEUS_HOME/lib/shared/wsit-3.0/jeus-ws.jar

  • JEUS_HOME/lib/shared/wsit-3.0/webservices-rt-3.0.1.jar

  • SYSTEM_LIB_DIR/resolver.jar

JMX(Java Management eXtensions)

  • SYSTEM_LIB_DIR/jmxremote.jar

웹 서비스에 대한 자세한 내용은 JEUS Web Service 안내서를 참고한다.

6.2. 콘솔에서 실행

콘솔에서 모듈을 실행하기 위해서 appclient 명령어를 사용한다. appclient는 JEUS_HOME\bin에 존재하는 스크립트로 클라이언트 컨테이너를 통해 애플리케이션 클라이언트 모듈을 실행한다.

다음은 JEUS에서 제공하는 클라이언트 컨테이너의 command line 형식이다.

  • 사용법

    appclient -client client_jar_path
             [-main main_class]
             [-cp classpath]
             application_arguments...

    다음은 명령어 옵션에 대한 설명이다.

    옵션 설명

    -client client_jar_path

    실행할 애플리케이션 클라이언트의 패스를 지정한다.

    [-main main_class]

    애플리케이션 클라이언트의 Main-Class를 지정한다. 클라이언트의 클래스 패스가 지정된 경로에 META-INF\MANIFEST.MF의 설정 정보에 Main-Class가 지정되어 있다면 이 옵션이 필요하지 않다.

    [-cp classpath]

    필요한 경우 클라이언트 실행에 필요한 클래스 패스를 지정한다.

  • 예제

    위의 예제를 실행하면 다음과 같다. 애플리케이션 클라이언트가 정상적으로 실행되기 위해서 Hello EJB가 deploy되어 있어야 한다.

    JEUS_HOME/samples/client/hello/hello-client/dist$ appclient -client hello-client.jar
    [2016.08.03 14:44:46][0] [t-1] [CLIENT-0050] Starting the Application Client Container - JEUS 9 Fix#0
    EJB output : Hello EJB!

    위의 내용 중 JEUS 로그를 출력하지 않으려면 다음을 추가로 설정한다.

    -Djeus.log.level=OFF

    로그 설정에 대한 자세한 설명은 JEUS Server 안내서의 Logging을 참고한다.