Top / J2EE / XDoclet

コンテンツ一覧

概要

WTPを使って開発をすると、JBossへデプロイすることができるだけでなく、jboss.xmlやjboss-web.xml,web.xmlやejb-jar.xmlを自動生成することができます。さらにはEJBの実装クラスを作成するだけで、めんどくさいその他のインタフェースファイルなども自動生成することができます。自動生成にはXDocletという、JavaDoc?コメントから各種設定ファイルを生成するツールが使われています。

準備

今回はJBossの環境を主においているので、JBossの設定ファイルを自動生成する用に設定しました。設定といっても簡単で、Eclipse上で、

ウィンドウ > 設定 >> J2EE注釈 >> XDoclet

でXDocletのホームディレクトリなどを入れておくだけです*1

JBossなどコンテナ依存の設定ファイルは、更に下の

XDoclet >> ejbdoclet
XDoclet >> webdoclet

などのチェックを入れておけばよいようです。

xdoclet.png

web.xmlの自動生成

コンテナ上のEJBビジネスロジックを使用するServlet*2は以下のようにしました。

/**
 * Servlet implementation class for Servlet: HogeServlet
 * 
 * @web.servlet name="HelloServlet" display-name="HelloServlet"
 * 
 * @web.servlet-mapping url-pattern="/hello"
 * @web.ejb-ref name = "ejb/HelloEJB" home = "hello.HelloEJBHome" remote =
 *        "hello.HelloEJB" type = "Session"
 * @jboss.ejb-ref-jndi jndi-name = "HelloEJBHoge" ref-name = "ejb/HelloEJB"
 */
public class HelloServlet extends HttpServlet {
  private HelloHome home = null;
  public void init(ServletConfig config) throws ServletException {
    Context context;
    try {
      context = new InitialContext();
    } catch (NamingException e) {
      throw new ServletException("JNDI InitialContextが取得できません.");
    }
    try {
      Object boundObject = context.lookup("java:comp/env/ejb/HelloEJB");
      home = (HelloHome) PortableRemoteObject.narrow(boundObject,
          HelloHome.class);
    } catch (NamingException e) {
      throw new ServletException("Homeインタフェースが取得できません.");
    }
    super.init(config);
  }

  public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    String ejbMessage;
    try {
      Hello remote = home.create();
      ejbMessage = remote.sayHello();
      System.out.println("ejbMessage = " + ejbMessage);
    } catch (Exception e) {
      ejbMessage = e.toString();
    }
    request.setAttribute("ejbMessage", ejbMessage);
    getServletContext().getRequestDispatcher("/HelloClient.jsp").forward(
        request, response);
  }
}

Servletの設定の出力

このうちクラスコメントの

@web.servlet name="HelloServlet" display-name="HelloServlet"
@web.servlet-mapping url-pattern="/hello"

の部分で、

<servlet>
   <servlet-name>HelloServlet</servlet-name> <- @web.servlet name="HelloServlet" 
   <display-name>HelloServlet</display-name> <- display-name="HelloServlet"
   <servlet-class>hello.web.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
   <servlet-name>HelloServlet</servlet-name>
   <url-pattern>/hello</url-pattern>         <- @web.servlet-mapping url-pattern="/hello"
</servlet-mapping>

というweb.xmlが出力されます。

ejb-refの出力

@web.ejb-ref name = "ejb/HelloEJB" home = "hello.HelloEJBHome" 
             remote = "hello.HelloEJB" type = "Session"

の部分で

<ejb-ref >
  <ejb-ref-name>ejb/HelloEJB</ejb-ref-name>  <- @web.ejb-ref name = "ejb/HelloEJB" 
  <ejb-ref-type>Session</ejb-ref-type>       <- type = "Session"
  <home>hello.HelloEJBHome</home>            <- home = "hello.HelloEJBHome" 
  <remote>hello.HelloEJB</remote>            <- remote = "hello.HelloEJB"
</ejb-ref>

というweb.xmlが出力されます。

jboss-web.xmlの自動生成

ejb-refの出力

また先の

@jboss.ejb-ref-jndi jndi-name = "HelloEJBHoge" 
                    ref-name = "ejb/HelloEJB"

の部分で、

<ejb-ref>
   <ejb-ref-name>ejb/HelloEJB</ejb-ref-name>  <- ref-name = "ejb/HelloEJB"
   <jndi-name>HelloEJBHoge</jndi-name>        <- @jboss.ejb-ref-jndi jndi-name = "HelloEJBHoge"
</ejb-ref>

というjboss-web.xmlが出力されます。

ejb-jar.xmlの自動生成

EJBのビジネスロジックは以下のようにしました。

/*
 * Enterprise Bean
 */
package hello.ejb;

import java.rmi.RemoteException;

import javax.ejb.EJBException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;

/**
 * 
 * @version $Revision: 1.3 $
 * @ejb.bean name="HelloEJB" display-name = "HelloEJB" jndi-name="HelloEJBHoge"
 *       type = "Stateless" view-type = "remote"
 * @ejb.interface remote-class="hello.ejb.Hello"
 * @ejb.home remote-class="hello.ejb.HelloHome"
 */
public class HelloBean implements SessionBean {
  /**
   * @return
   * @throws RemoteException
   * @ejb.interface-method view-type= "remote"
   */
  public String sayHello() throws RemoteException {
    System.out.println("hoge");
    return "Hello EJB !";
  }

  public void setSessionContext(SessionContext arg0) throws EJBException,
      RemoteException {
  }

  public void ejbRemove() throws EJBException, RemoteException {
  }

  public void ejbActivate() throws EJBException, RemoteException {
  }

  public void ejbPassivate() throws EJBException, RemoteException {
  }
}

このうちクラスコメントの

@ejb.bean name="HelloEJB" display-name = "HelloEJB" jndi-name="HelloEJBHoge"
      type = "Stateless" view-type = "remote"
@ejb.interface remote-class="hello.ejb.Hello"
@ejb.home remote-class="hello.ejb.HelloHome"

の部分で、

<session >
  <description><![CDATA[]]></description>
  <display-name>HelloEJB</display-name>    <- display-name = "HelloEJB"
  <ejb-name>HelloEJB</ejb-name>            <- @ejb.bean name="HelloEJB"
  <home>hello.ejb.HelloHome</home>         <- @ejb.home remote-class="hello.ejb.HelloHome"
  <remote>hello.ejb.Hello</remote>         <- @ejb.interface remote-class="hello.ejb.Hello"
  <ejb-class>hello.ejb.HelloEJBSession</ejb-class>
  <session-type>Stateless</session-type>   <- type = "Stateless"
  <transaction-type>Container</transaction-type>
</session>

というejb-jar.xmlが出力されます。

jboss.xmlの自動生成

また

<session>
   <ejb-name>HelloEJB</ejb-name>       <- @ejb.bean name="HelloEJB"
   <jndi-name>HelloEJBHoge</jndi-name> <- jndi-name="HelloEJBHoge"
   また、実際にコンテナにデプロイされる実際の(?)JNDI名
  <method-attributes>
  </method-attributes>
</session>

もあわせて出力されます。

その他のインタフェースファイルの作成

上のXDocletの記述で

  • sayHello()メソッドをインタフェースに持つ、Helloインターフェース(extends EJBObject)
  • ビジネスロジック*3を記述したこのファイル(HelloBean? implements SessionBean?)をextendsしたHelloEJBSessionクラス
  • HelloインタフェースをCreateするメソッドを持つ、HelloHome? インタフェース(extends EJBHome)
  • ユーティリティクラス HelloEJBUtilクラス

のファイルも併せて自動生成されます。

ビジネスロジックの生成

また、この場合のビジネスロジックのインタフェースであるhello.ejb.Helloインタフェースに、

  public java.lang.String sayHello(  )
     throws java.rmi.RemoteException;

が定義されていますが、これは

/**
 * @return
 * @throws RemoteException
 * @ejb.interface-method view-type= "remote"
 */
public String sayHello() throws RemoteException {
    System.out.println("hoge");
    return "Hello EJB !";
}

@ejb.interface-method view-type= "remote"

によって出力されます。

これはいいなあ

使ってみてわかるのが、EJBのめんどくさいいろいろなインタフェースを書かなくても、XDocletが自動でいろいろ生成してくれることがわかります。このアプローチはEJB3.0でも全面的に採用されていて、JavaDoc?のコメントがAnnotationになるなどいろいろ洗練されて実装されるようです。

ユーティリティクラスを使う

XDocletを使った場合、ユーティリティクラスHelloEJBUtilクラスも生成されます。このユーティリティクラスはHomeインタフェースをキャッシュして返すなど便利なメソッドを提供してくれます。具体的には、通常

Object boundObject = context.lookup("java:comp/env/ejb/HelloEJB");
home = (HelloHome) PortableRemoteObject.narrow(boundObject,HelloHome.class);

とやっているところを、

home = HelloEJBUtil.getHome();

とすることができます。またPropertiesクラスを渡して、InitialContext?を初期化することもできます。こんな感じです。

Properties props = new Properties();
props.put(Context.PROVIDER_URL, "localhost:1099");
home = HelloEJBUtil.getHome(props);

ファイルのマージ

Welcomeファイルの場所やcontext-paramなど、ココのファイルに依存しない情報はどこに書くのかよくわからなかったのですが、XDocletにはマージという概念があるようです。詳細はXDocletを使った設定ファイルなどの作成の効率化を参照のこと。


この記事は

選択肢 投票
おもしろかった 3  
そうでもない 0  
  • わからないこと。他のライブラリのサーブレットなど、jarに入っているServletのタグ付けの方法。どのクラスにも属さないようなメタ的な内容のタグ付けの方法。たとえばStrutsだったら、DynaForm?みたいなヤツのタグ付けの方法。。。わかんないこと結構あるね -- きの? 2005-11-15 23:01:39 (火)
  • Annotationが書いてあるソースは構文エラーになっちゃう。 http://opensource2.atlassian.com/projects/xdoclet/browse/XJD-41 にあるとおり、xjavadoc-1.1-j5-v4.jarに入れ替えたら一応Antでのビルドは成功した。でもなんかエラーでてるね。 -- きの? 2006-02-23 18:22:32 (木)
  • web.xmlに関しては、listeners.xml、web-settings.xmlなどにタグ付けを書いておけば、マージされるみたいです。 -- きの? 2006-02-23 18:25:09 (木)

Top / J2EE / XDoclet

現在のアクセス:10487


*1 XDocletはあらかじめダウンロードしてどっかに解凍しておきましょう。
*2 EJBクライアントといったほうがよい?
*3 っつってもHello EJBってかえすだけ

添付ファイル: filexdoclet.png 577件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2008-08-21 (木) 16:58:34 (3738d)