// 下階層用テンプレート
#topicpath
----
//ここにコンテンツを記述します。
#contents

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


**準備 [#j48c717b]
今回はJBossの環境を主においているので、JBossの設定ファイルを自動生成する用に設定しました。設定といっても簡単で、Eclipse上で、
 ウィンドウ > 設定 >> J2EE注釈 >> XDoclet
でXDocletのホームディレクトリなどを入れておくだけです((XDocletはあらかじめダウンロードしてどっかに解凍しておきましょう。))。

JBossなどコンテナ依存の設定ファイルは、更に下の
 XDoclet >> ejbdoclet
 XDoclet >> webdoclet
などのチェックを入れておけばよいようです。

#ref(xdoclet.png)

**web.xmlの自動生成 [#ma3ff33e]
コンテナ上のEJBビジネスロジックを使用するServlet((EJBクライアントといったほうがよい?))は以下のようにしました。
 /**
  * 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の設定の出力 [#h1ba1bd8]
このうちクラスコメントの
 @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の出力 [#ie8d8902]
 @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の自動生成 [#f49a574f]
***ejb-refの出力 [#b857b90b]
また先の
 @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の自動生成 [#e4eec02f]
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の自動生成 [#u20de1cd]
また
 <session>
    <ejb-name>HelloEJB</ejb-name>       <- @ejb.bean name="HelloEJB"
    <jndi-name>HelloEJBHoge</jndi-name> <- jndi-name="HelloEJBHoge"
    また、実際にコンテナにデプロイされる実際の(?)JNDI名
   <method-attributes>
   </method-attributes>
 </session>
もあわせて出力されます。

***その他のインタフェースファイルの作成 [#r5edd00b]
上のXDocletの記述で

-sayHello()メソッドをインタフェースに持つ、Helloインターフェース(extends EJBObject)
-ビジネスロジック((っつってもHello EJBってかえすだけ))を記述したこのファイル(HelloBean implements SessionBean)をextendsしたHelloEJBSessionクラス
-HelloインタフェースをCreateするメソッドを持つ、HelloHome インタフェース(extends EJBHome)
-ユーティリティクラス HelloEJBUtilクラス

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







***ビジネスロジックの生成 [#i9547fc5]
また、この場合のビジネスロジックのインタフェースである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"
によって出力されます。




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


**ユーティリティクラスを使う [#id866ec0]
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);







----
この記事は
#vote(おもしろかった,そうでもない)

#comment
#topicpath


SIZE(10){現在のアクセス:&counter;}

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS