본문 바로가기

Dev.../웹서비스

[펌] XDoclet 사용법

제3회 Ant(으)로EJB개발을 효율화


오카모토 타카시
NTT데이터 기술개발 본부/Ja-Jakarta Project
2003/2/19


 본고에서는 , 전회 「Ant으로Java의 빌드를 간단하게 한다」 것Ant의 사용법의 응용편이라고 하는 것으로 ,Ant의 태스크로서 이용할 수 있는 코드 생성 엔진XDoclet을 이용해EJB를 간단하게 생성하는 방법에 대해 해설합니다. XDoclet(을)를 이용하면(자) ,1개의 것JavaBean을 작성하는 것만으로 ,EJB에 필요한 리모트/홈 인터페이스 , 각종 배치 기술자(이하DD) 를 자동적으로 생성할 수 있게 됩니다. XDoclet의 이용은 ,EJB개발의 효율화 , 관리의 수고의 삭감에 매우 효과가 있습니다. EJB의 개발의 번잡함이 곤란하고 있는 사람 ,EJB을 사용해 보고 싶지만 , 만드는 방법이 어려워서 사용할 수 없었던 사람은 , 꼭 본고를 읽어 실천해 보세요.

 번잡한EJB개발을 편하게 하고 싶다

 여러분은 ,EJB을 어떻게 해 작성할까요? 필자가 처음EJB의 프로그램을 썼을 때는 , 텍스트 문자 편집기를 사용해EJB를 작성했습니다. 텍스트 문자 편집기를 사용해EJB의 코드를 쓰는 작업은 , 통상의 것JavaBean을 작성하는데 비교하면(자) 매우 큰 일입니다. 예를 들면 , open source의 어플리케이션 서버JBoss상에서 움직이는 간단한CMP을 1개만드는데나 , 아래 표와 같이 복수의 파일이 필요합니다.

파일해설
HelloRemote 리모트 인터페이스
HelloHome 홈 인터페이스
HelloCMPCMP엔티티Bean본체
ejb-jar.xmlEJB용의 배치 기술자
jboss.xmlJBoss용의 배치 기술자
jbosscmp-jdbc.xml JBoss용의 배치 기술자(CMP용)
표1 CMP엔티티Bean를 작성하는데 필요한 파일

 1개의 것Bean을 작성하는데 , 이만큼의 파일이 필요하게 되면(자) , 개발 효율의 저하가 용이하게 예상됩니다. 그리고 , 이러한 파일은 서로 의존하고 있기 (위해)때문에 ,HelloCMP에 메소드를 추가했을 경우 ,HelloHome/HelloRemote등 도 변경할 필요가 있어 , 메인트넌스성도 나빠집니다.

 그리고 ,CMP엔티티Bean를 사용하면(자) ,SQL문장을 이용한JDBC에 의한 코딩을 실시하는 일 없이 데이타베이스를 이용할 수가 있기 (위해)때문에 , 개발이 편해진다고 말해지고 있습니다만 , 그 이야기를 그대로 받아들여CMP엔티티Bean를 이용해 아픈 눈을 당한 (분)편도 안에는 계(오)시는 것은 아닐까요.

 EJB(을)를 이용하고 있는 현장에서는 , 시판의 것IDE을 이용해 개발하고 있는 케이스가 많을 것입니다. 그러나 ,Java Solution포럼으로 간 「제5회 독자 앙케이트:IDE/AP서버/체제의 이용 상황을 총괄」을 본다고 알 수 있도록(듯이) ,Java의 이용자의 상당수는 , 텍스트 문자 편집기를 이용해 코드를 쓰고 있는 것이 현상입니다. 그리고 , 비록IDE을 사용했다고 해도 ,IDE의 기능을 적절히 사용하지 않고 원시 코드에 직접 메소드를 추가하고 있는 동안에 , 파일의 정합성이 잡히지 않게 된다고 하는 일도 있습니다.

 「무엇으로1개의 것EJB을 작성하는데 , 이렇게 많은 파일이 필요하게 되는 것일까? 1개의 것EJB을 작성하는데 ,1개의Java코드로 기술할 수 있으면(자)……」라고EJB의 개발에 종사한 것이 있는 사람이라면 누구든지 한 번은 생각하겠지요. 이 「EJB개발자의 꿈」을 실현해 주는 것이 , 이번 소개하는XDoclet인 것입니다.

 XDoclet(이)란?

 XDoclet(이)란 , 코드 생성 엔진이며 ,Java를 위한 애트리뷰트(attribute) 지향 프로그래밍을 제공하는 것입니다. 애트리뷰트(attribute) 지향과는 , 유저가 특수한JavaDoc태그를 코드중에 기술하는 것 에 의해 , 그 코드에 대한 애트리뷰트(attribute)(속성)을 주어 코드의 자동 생성에 대한 힌트로 합니다. XDoclet(은)는 소스중에 파묻힌 속성으로부터 , 다양한 파일(EJB의 경우 , 홈/리모트 인터페이스 , 각종DD) 을 자동 생성합니다(그림1).

그림 1 XDoclet에 의한 코드 생성

 XDoclet(을)를 사용하는 것으로 , 다음과 같은 이점이 있습니다.

1.복수의 코드에 분산하고 있던 원시 코드를1개의 것JavaBean에 정리할 수가 있어 개발의 효율화와 코드의 대폭적인 삭감을 실시할 수가 있습니다.XDoclet의Web페이지에 의하면 , 약85%의 코드를XDoclet이 자동 생성해 준다고 쓰여져 있습니다.

2.파일이1개가 된 것에 의해 , 메인트넌스의 수고를 큰폭으로 삭감합니다. EJB본체 , 인터페이스 ,DD사이의 부정합이 생기는 일도 없습니다.

3.어플리케이션 서버의 종류나 버젼의 차이에 의해DD가 다릅니다만 ,DD은XDoclet이 자동적으로 생성해 주므로 , 개발자는 , 어플리케이션 서버마다의 차이를 의식할 필요가 없습니다. 그리고 , 어플리케이션 서버 고유의 설정도 ,Ant의 인수나 태그의 코멘트로 간결하게 기술할 수 있습니다.

 본고에서는 ,EJB의 생성에 대한 보고 해설합니다만 ,XDoclet에는Web어플리케이션 ,hibernate/jdo등의O-R매핑 ,JMX의 개발을 지원하는 태스크가 준비되어 있습니다.

태스크기능
ejbdoclet EJB개발 지원
webdoclet Servlet/JSP개발 지원
jdodocletO-R매핑(JDO(*1) ) 개발 지원
hibernatedocletO-R매핑(hibernate(*2))개발 지원
jmxdoclet JMX개발 지원
표2 XDoclet그리고 제공되고 있는 태스크

*1:Java Data Object. JSR-000012(으)로서JCP로 표준화 되고 있는O-R매핑의 표준API. 자세한 것은http://access1.sun.com/jdo/을 참조.
*2:SourceForge그리고 개발되고 있는O-R매핑 툴(http://sourceforge.net/projects/hibernate/)

 그리고 ,XDoclet는 확장성이 뛰어나 코드 생성의 템플릿을 작성하는 것으로써 , 다른 어플리케이션/기술에 대응시킬 수가 있습니다. 확장성의 이점은 겉(표)2에 나타내도록(듯이) 다양한 태스크가 제공되고 있는 것으로부터도 분 빌리고지요.

 덧붙여XDoclet 1.x계에서는 , 이 템플릿에XML베이스로 기술된XDoclet독자적인 구문을 이용하고 있습니다만 ,XDoclet 2.0으로부터Jakarta의 템플릿 엔진Velocity도 이용할 수 있게 됩니다. Velocity(은)는 심플한 구문에 강력한 기능을 갖추고 있어XDoclet의 확장성은 한층 더 향상하겠지요.

 XDoclet(은)는 ,Jakarta프로젝트로 개발되고 있는 것은 아닙니다만 , 벌써 말한 것처럼Ant/Velocity등 과 깊은 관련이 있습니다. 그리고 ,Ant 2.0의proposal디렉토리에는 ,XDoclet이 포함되어 있어Ant 2.0로부터 는 디폴트로 첨부될 것 같습니다.

 XDoclet에 의한EJB생성

 그러면 , 실제로AntXDoclet를 이용해EJB를 작성해 봅시다. 여기에서는 ,JBoss그리고 이용 가능한EJB을XDoclet을 사용해 작성합니다. 작성하는EJB은 , 메일 주소와 이름을 데이타베이스의 테이블로 관리하는CMP엔티티Bean으로 ,MemberBean라고 명명합니다. MemberBean(은)는 , 필드에emailname를 가져 ,email를 프라이머리 키로 합니다. 그리고 , 트랜잭션(transaction)는 , 특히 고려하지 않는 것으로 합니다. 이MemberBean클래스의 샘플을리스트1에 나타냅니다.

리스트1 MemberBean.java
package test.ejb;

import javax.ejb.*;
import java.util.Collection;

/** 
   * EJB전체에 대한 설정
 * @ejb.bean
 *  type="CMP"             EJB의 타입
 *  name="Member"          EJB의 이름
 *  primkey-field="email"  프라이머리 키필드
 *  view-type="remote"     뷰타이프
 * 
 * @ejb.finder             finder
 *  signature="Collection findAll()"
 *  transaction-type="NotSupported"
 * @ejb.persistence
 *  table-name="member"    O-R매핑을 실시하는 테이블명
*/
public abstract class MemberBean 
extends BaseEntityBean implements EntityBean {

/**
 * getEmail메소드(email필드)에 대한 설정
 *
 * @ejb.interface-method    리모트 인터페이스를 생성
 * @ejb.pk-field            이 메소드에 대응하는 필드를
 *                          프라이머리 키로 지정
 * @ejb.persistence 데이타베이스의 테이블과의 매핑의 지정
 *  column-name="email"     컬럼명
 *  sql-type="VARCHAR"      SQL의 타입
 */
 public abstract String getEmail();

 /**
 * setEmail메소드에 대한 설정
 *
 * @ejb.interface-method    리모트 인터페이스를 생성
 */
 public abstract void setEmail(String email);

 /**
 * getName메소드(name필드)에 대한 설정
 *
 * @ejb.interface-method   리모트 인터페이스를 생성
 * @ejb.persistence        데이타베이스의 테이블과의 매핑의 지정
 *  column-name="name"     컬럼명
 *  sql-type="VARCHAR"     SQL의 타입
     */

public abstract String getName();
    /**
     * setName메소드에 대한 설정
     *
     * @ejb.interface-method 리모트 인터페이스를 생성
     */
   public abstract void setName(String name);

    /**
     * EJB의 생성에 대한 설정
     *
     * @ejb.create-method create메소드를 생성
     */
    public String ejbCreate(String email)
 throws CreateException {
        setEmail(email);
        return null;
    }

}

※적자 부분은 주석이며 , 실제의 리스트에는 포함되지 않습니다.
주:여기에서는 , 코드를 알기 쉽게 하기 위해서 , 엔티티Bean에 공통된 메소드를 실장한 추상 클래스BaseEntityBean를 준비해 , 그 클래스를 계승해MemberBean를 실장하고 있습니다.

 XDoclet(을)를 이용하는 경우 , 코멘트에 묻은 태그(리스트 1의 청자 부분)에 의해 ,EJB의 속성을 지정합니다. 이 속성은 , 클래스 코멘트와 메소드 코멘트에 의해 , 각각 다음과 같이 지정 항목이 다릅니다.

●클래스 코멘트
EJB의 타입 ,EJB이름 , 테이블명 , 프라이머리 키필드의 지정 등 ,EJB전체에 걸치는 속성을 지정합니다.

●메소드 코멘트
O-R매핑을 실시할 때의 , 데이타베이스의 테이블의 컬럼과 필드의 대응 붙여 그 메소드에 대한 리모트 인터페이스를 생성하는지 어떤지 ,create메소드를 생성하는지 어떤지 등 , 메소드에 대한 속성을 지정합니다.

 덧붙여XDoclet의EJB생성에 사용할 수 있는 태그에 대한 자세한 것은 ,Tag Reference for @ejb사이트를 봐 주세요.

■Ant의 빌드 파일

 XDoclet의 태스크는 , 처음은Ant에는 포함되어 있지 않습니다. 제공되어 있지 않은 태스크를 이용하려면 ,taskdef태스크를 이용해 , 다음과 같이 태스크를 정의할 필요가 있습니다.

<taskdef name="ejbdoclet"
classname="xdoclet.modules.ejb.EjbDocletTask"
classpathref="class.path"/>

 여기에서는 ,xdoclet.modules.ejb.EjbDocletTask클래스를ejbdoclet태스크로서 정의합니다. XDoclet에 한정하지 않고 , 확장 태스크를 이용하는 경우에는 ,taskdef을 이용하므로 , 기억해 두면(자) 좋을 것입니다. 정의한ejbdoclet태스크를 이용하려면 , 다음과 같이 기술합니다.

<ejbdoclet
    destdir="${gen-src.dir}" 생성된 코드를 출력하는 디렉토리
    excludedtags="@version,@author,@todo" 처리 대상에서 제외하는 태그
    ejbspec="2.0" EJB사양의 버젼
>


<!-- 원시 파일의 지정 -->
<fileset dir="${src.dir}">
    <include name="test/ejb/*Bean.java"/>
</fileset>

<!-- CMP엔티티Bean생성 -->
<entitycmp/>

<!-- 리모트/홈 인터페이스 생성 -->
<remoteinterface/>
<homeinterface/>

<!-- ejb-jar.xml의 생성 -->
<deploymentdescriptor
    destdir="${meta-inf.dir}" DD을 생성하는 디렉토리
/>

<!-- JBoss고유의 것DD의 생성 -->
<jboss
    version="3.0" JBoss의 버젼
    destdir="${meta-inf.dir}" DD을 생성하는 디렉토리
/>

</ejbdoclet>

※적자 부분은 주석이며 , 실제의 리스트에는 포함되지 않습니다.

  그런데 , 실제로 ,XDoclet라고JBoss를 이용해 , 샘플 프로그램으로부터EJB를 생성해 이용해 봅시다.

 인스톨과 실행

 Ant(을)를 전회의 기사에 따라 , 인스톨 해 두어 주세요. 그리고 ,J2SDK(1.4.1_01) ,JBoss,XDoclet를 아래와 같은 디렉토리에 인스톨 합니다.

JBoss C:\jboss-3.2.0RC1_tomcat-4.1.18
XDocletC:\ xdoclet
XDocletC:\j2sdk1.4.1_01
주:본고에서는 ,Windows을 대상으로 기술하고 있습니다만 , 패스명을 변경하면 ,UNIX그렇지만 이용 가능합니다. 그리고 , 다른 디렉토리에 인스톨 한 사람은 적당 읽어 바꾸어 주세요.

●XDoclet의 인스톨
 http://sourceforge.net/project/showfiles.php?group_id=31602(으)로부터 ,XDoclet-bin-1.2b2.zip를 다운로드해 주세요. C:\xdoclet디렉토리를 작성해 , 이 디렉토리에 해동해 주세요.

●JBoss의 인스톨
 http://sourceforge.net/project/showfiles.php?group_id=22866(으)로부터jboss-3.2.0RC1_tomcat-4.1.18.zip 를 다운로드해 주세요. 다운로드한zip파일을 ,C:\디렉토리에 그대로 해동해 주세요.

 XDoclet(와)과JBoss의 인스톨이 완료하면(자) ,C:\jboss-3.2.0RC1_tomcat-4.1.18디렉토리(이하 ,JBOSS_HOME라고 기술) 와C:\XDoclet디렉토리에 각각의 파일이 인스톨 되고 있는 것을 확인해 주세요. 다른 디렉토리에 인스톨 했을 경우(특히UNIX를 이용하는 (분)편 ) 나 , 다른 버젼의 것JBoss을 이용하는 (분)편은 적당 읽어 바꾸어 주세요.

  이번 소개한 샘플을여기로부터 다운로드해 ,C:\디렉토리에 해동해 주세요. 샘플에는 , 다음의 파일이 포함됩니다.

파일설명
build.xml Ant의 빌드 파일
build.properties 프롭퍼티 파일(build.xml로부터
인클루드 된다. JBoss(을)를XDoclet의 패스
로 설정한다 )
src/test/ejb/MemberBean.javaXDoclet로 이용하는EJB의 원시 코드
src/TestClient.java테스트용의 코드

 만약 ,XDoclet이라고JBoss를 상기로 지정한 디렉토리와 다른 디렉토리에 인스톨 했을 경우에는 ,build.properties파일에 포함되는jboss과XDoclet의 루트 디렉토리의 패스를 변경해 주세요. 이것으로 준비는 완료입니다.

그런데 ,Ant를 사용해 ,EJB를 생성해 봅시다. C:\XDoclet-sample디렉토리로 이동해 ,

C:\xdoclet-sample> ant

라고 실행하면(자) ,EJB가 생성됩니다. Ant(을)를 실행하면(자) , 우선 ,ejbdoclet타겟으로보다 ,src/test/ejb/MemberBean.java에 있는MemberBean.java으로부터 다음의 파일이 생성됩니다.

build/gen-src/test/ejb/MemberCMP.java CMP엔티티Bean본체
build/gen-src/test/ejb/Member.java 리모트 인터페이스
build/gen-src/test/ejb/MemberHome.java홈 인터페이스
build/meta-inf/ejb-jar.xmlEJB의 표준DD
build/meta-inf/jboss.xmlJBoss고유의DD
build/meta-inf/jbosscmp-jdbc.xml JBoss고유의DD(CMP용)

 단1개의 것MemberBean.java으로부터EJB에 필요한 파일이 차례차례로 생성되는 모양은 마치 마법 같아 , 확실히 하마이오니절의 부엌입니다. 이러한 파일은 , 컴파일 되어 ,dest/xdoclet-sample.jar에EJB의jar파일로서 생성됩니다.

 동작 확인

 xdoclet-sample.jar(을)를 ,JBoss을 인스톨 한 디렉토리아래의server/default/deploy디렉토리에 카피해 ,JBOSS_HOME\bin\run.bat파일을 실행(더블 클릭 혹은 , 커멘드 라인으로부터 실행)합니다. 이것으로 ,JBoss가 기동합니다.

 무사JBoss가 기동하면(자) , 작성했다EJB를 테스트하는 클라이언트를 실행해 봅시다. c:\xdoclet-samples\build\classes디렉토리로 이동해 , 다음과 같이 실행합니다 (여기에서는J2SDK 1.4의 경우입니다만 ,J2SDK 1.3환경에서 올바르게 동작하지 않는 경우는 ,C:\jboss-3.2.0RC1_tomcat-4.1.18\client이하의jar파일 모두에게 클래스 패스를 통해 주세요 ).

C:\>cd C:\xdoclet-sample\build\classes
C:\>SET CLASSPATH=C:\jboss-3.2.0RC1_tomcat-4.1.18\client\jbossall-client.jar;


C:\xdoclet-sample\client>java TestClient create okamototk@nttdata.co.jp "Takashi Okamoto" 
[create]
email:okamototk@nttdata.co.jp
name :Takashi Okamoto


C:\xxdoclet-sample\client>java TestClient find okamototk@nttdata.co.jp
[find]
email:okamototk@nttdata.co.jp
name :Takashi Okamoto


C:\xdoclet-sample\client>java TestClient remove okamototk@nttdata.co.jp
[remove]
email:okamototk@nttdata.co.jp
name :Takashi Okamoto

 당연히 , 등록한 멤버는 , 데이타베이스에 영속화 되고 있으므로 , 멤버를 삭제하지 않는 한 ,JBoss을 일단 정지해 재기동해도 검색할 수 있습니다.

 XDoclet의 유연성

 XDoclet(을)를 이용하면(자) , 간단하게EJB를 작성 가능할 뿐만 아니라 ,JavaBean의 태그나ejbdoclet의 옵션을 조금 변경하는 것만으로 ,EJB의 설정을 간단하게 바꿀 수가 있습니다. 여기에서는 , 방금전의 샘플을 기본으로 해 , 데이터 소스의 지정 , 로컬EJB의 작성 ,WebLogic용무의 것DD의 작성을 통해 ,XDoclet의 유연성을 봅시다.

■데이터 소스를 지정

 샘플에서는 ,JBoss의 디폴트의 데이터 소스(java:/DefaultDS) 를 이용하게 되어 있습니다만 , 명시적으로 데이터 소스를 지정하려면 , 다음과 같이ejbdoclet태스크에valueobject태그를 포함해jboss태그에 데이터 소스를 지정합니다.

<!-- Value오브젝트 생성 -->
<valueobject />

<!-- JBoss고유의 것DD의 생성 -->
<jboss
  version="3.0"
  destdir="${meta-inf.dir}"
  datasource="java:/PostgreSQLDS"
데이터 소스명
  datasourceMapping="PostgreSQL"
데이타베이스 타입
/>
주:샘플에서는 ,Value오브젝트를 생성합니다만 , 데이터 소스의 설정을 하기 위해서 필요하고 있습니다. Value오브젝트를 생성하는 경우는 ,MemberBean.java그리고@ejb.value-object name="Member"로 합니다.

■로컬EJB의 작성

 이번은 , 통상의 것CMP엔티티Bean을 작성했습니다만 ,XDoclet을 이용하면(자) ,EJB 2.0로부터 서포트된 로컬EJB도 간단하게 작성할 수가 있습니다. 쿠라스타그의 아래와 같은view-type

@ejb.bean

...

view-type="remote"
뷰타이프

을 다음과 같이local로 변경합니다.

view-type="local" 뷰타이프

 그리고 ,build.xml의 아래와 같은 부분

<remoteinterface/>
<homeinterface/>

<localinterface/>
<localhomeinterface/>

과 로컬 인터페이스를 생성하도록(듯이) 변경하는 것만으로 , 로컬EJB을 작성할 수가 있습니다. 생성되는 파일의 이름도 ,Member(리모트 인터페이스) 가MemberLocal(로컬 인터페이스) 에 ,MemberHome(홈 인터페이스) 가MemberLocalHome(로컬 홈 인터페이스)로 바뀝니다.

 view-type(을)를both로 해 , 리모트EJB의 설정과 로컬EJB의 설정을 쓰는 것으로 , 양쪽 모두의 것EJB을 동시에 생성할 수도 있습니다.

■WebLogic용무의 것DD을 작성

 WebLogic용무의 것DD을 작성하려면 ,ejbdoclet태스크중에jboss태그 대신에weblogic태그를 정의합니다.

<weblogic
  version="6.1"
  destdir="${samples.meta-inf.dir}"
  datasource="java:/samplesDataSource"
  persistence="weblogic"
/>

 jboss태그와weblogic태그를 동시에 정의하면 ,JBoss용무와WebLogic용무의 것DD이 생성되므로 ,2개의 어플리케이션 서버에 대응했다EJB를 작성하는 것이 가능합니다. 그 외 ,WebSphere(websphere태그)/JOnAS(jonas태그)/JRun(jrun태그) 등에 대응하고 있습니다. 이와 같이 간단하게 다른 어플리케이션 서버용의 것DD을 작성할 수가 있습니다.

 보시는 바와 같이 ,XDoclet를 이용하면(자) ,ejbdoclet태스크의 파라미터나JavaBean의 태그를 변경하는 것만으로 유연하게EJB의 생성 룰을 바꿀 수가 있습니다.

 통계

 이번은 , 응용편이라고 하는 것으로 ,XDoclet를 이용했다EJB의 작성 방법에 대해 소개했습니다. XDoclet(을)를 이용하면(자) , 고가의IDE를 구입하는 일 없이 ,EJB의 개발을 간단하게 실시할 수 있게 됩니다. 확실히 혁명적이라고 해도 좋을 것입니다. 지금까지EJB를 경원하고 있던 (분)편도 ,XDoclet를 사용해 ,EJB에 접해 보면 어떻습니까?

필자 프로필
오카모토 타카시(오카모토 타카시)

현재 , 주식회사NTT데이터 기술개발 본부에 소속. Web서비스 기술의 연구개발에 종사한다. 개인에서는 ,Debian/GNU Linux을 시작으로 한 다양한 open source 프로젝트에 콘트리뷰트 하고 있어 ,Jakarta그럼 , 프로덕트의 국제화/일본어에의 로컬라이즈를 중심으로서 활동하고 있다.