// 下階層用テンプレート #topicpath ---- ***コンテンツ一覧 [#g5c49561] #ls2 ***概要 [#gc5fed27] //ここにコンテンツを記述します。 #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); **ファイルのマージ [#k90941ae] Welcomeファイルの場所やcontext-paramなど、ココのファイルに依存しない情報はどこに書くのかよくわからなかったのですが、XDocletにはマージという概念があるようです。詳細は[[XDocletを使った設定ファイルなどの作成の効率化>JBoss/TODO/5]]を参照のこと。 -[[マージポイントの説明:http://xdoclet.sourceforge.net/olddocs/webdoclet.html]] ---- この記事は #vote(おもしろかった,そうでもない) -わからないこと。他のライブラリのサーブレットなど、jarに入っているServletのタグ付けの方法。どのクラスにも属さないようなメタ的な内容のタグ付けの方法。たとえばStrutsだったら、DynaFormみたいなヤツのタグ付けの方法。。。わかんないこと結構あるね -- [[きの]] &new{2005-11-15 23:01:39 (火)}; #comment #topicpath SIZE(10){現在のアクセス:&counter;}