諸事情によりIDEなしでEJB2+Servlet+JSPなEnterprise Applicationを構築したりする必要があったのでメモ。
想定するアプリケーション構造
Web Browser <---> JSP <---> Servlet <---> EJB(Stateless Session Bean) <---> DAO(POJO) <---> DB
- Web Browser
- クライアントアプリ。
- JSP
- 入力と出力用画面。Sendボタン押下でto入力欄の内容をServletに送信、結果をResult欄に表示する。
- Servlet
- EJBを生成し、JSPからの入力を渡してリモートメソッドの実行、結果を受け取りJSPへ返す。
- EJB
- 入力文字列を加工して結果を返却する。
DB用意するのが面倒なのでDAO以降は省略。EJB使っているわけではなく単なるPOJOなので調べる必要なし。
アプリケーションサーバにはWebLogic 9.2MP3を利用。ちょい古めのバージョンだが諸事情のため。
EARの構造
EAR(Enterprise Archive)ファイルは下記のようなディレクトリ構造を持つZIPファイル*1。jarコマンドで作成する。application.xmlファイルが含まれるMETA-INFディレクトリと複数のWARファイルおよび複数のEJB-JAR(EJBを使っている場合)ファイルで構成される。
/ META-INF/ application.xml weblogic-application.xml hello.war hello.jar
application.xmlファイルにはEARファイルに含まれるWARファイルとEJB-JAR ファイルの名前を定義する感じ。ここでWARファイルに対してコンテキストルートを定義すると、WARファイル内のweb.xmlで定義されたコンテキストルートは上書きされる*2。
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE application PUBLIC '-//Sun Microsystems, Inc.//DTD J2EE Application 1.2//EN' 'http://java.sun.com/j2ee/dtds/application_1_2.dtd'> <application> <description>Hello Enterprise Application</description> <module> <ejb>hello.jar</ejb> </module> <module> <web> <web-uri>hello.war</web-uri> <context-root>hello</context-root> </web> </module> </application>
weblogic-application.xmlファイルはWebLogic用のapplication.xmlファイル。最小構成においては特に書くことない。一応用意する。
<?xml version="1.0" encoding="ISO-8859-1"?> <wls:weblogic-application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wls="http://www.bea.com/ns/weblogic/90" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/j2ee_1_4.xsd http://www.bea.com/ns/weblogic/90 http://www.bea.com/ns/weblogic/90/weblogic-application.xsd"> </wls:weblogic-application>
EJB-JARの構造
EJB-JAR(EJB Java Archive)は下記のようなディレクトリ構造を持つZIPファイル。jarコマンドで作成する。ejb-jar.xmlファイルが含まれるMETA-INFディレクトリとEJBのclassファイル(Homeインタフェース、Remoteインタフェース、Beanクラス)で構成される。
/ META-INF/ ejb-jar.xml weblogic-ejb-jar.xml net/ jibunstyle/ hello/ ejb/ Hello.class HelloBean.class HelloHome.class
ejb-jar.xmlファイルには作成したEJB関連クラスのFQCNとBeanの種類などを定義する。
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN' 'http://java.sun.com/dtd/ejb-jar_2_0.dtd'> <ejb-jar> <enterprise-beans> <session> <ejb-name>Hello</ejb-name> <home>net.jibunstyle.hello.ejb.HelloHome</home> <remote>net.jibunstyle.hello.ejb.Hello</remote> <ejb-class>net.jibunstyle.hello.ejb.HelloBean</ejb-class> <session-type>Stateless</session-type> <transaction-type>Bean</transaction-type> </session> </enterprise-beans> </ejb-jar>
weblogic-ejb-jar.xmlはWebLogic用のejb-jar.xmlファイル。EJB名とそのJNDI名を定義しておく。weblogic-application.xmlやweblogic.xmlでは何も記載いらなかったのでこれも同様である気がするが調べるのが面倒なのでとりあえず。
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE weblogic-ejb-jar PUBLIC '-//BEA Systems, Inc.//DTD WebLogic 6.0.0 EJB//EN' 'http://www.bea.com/servers/wls600/dtd/weblogic-ejb-jar.dtd'> <weblogic-ejb-jar> <weblogic-enterprise-bean> <ejb-name>Hello</ejb-name> <jndi-name>Hello</jndi-name> </weblogic-enterprise-bean> </weblogic-ejb-jar>
以下、EJB関連のクラス。
package net.jibunstyle.hello.ejb; import javax.ejb.EJBObject; import java.rmi.RemoteException; /** * Remoteインタフェース */ public interface Hello extends EJBObject { public String say(String to) throws RemoteException; }
package net.jibunstyle.hello.ejb; import java.rmi.RemoteException; import javax.ejb.SessionBean; import javax.ejb.SessionContext; /** * Beanクラス */ public class HelloBean implements SessionBean { public String say(String to) { return "Hello, " + to; } public void setSessionContext(SessionContext sc) {} public void ejbCreate() {} public void ejbRemove() {} public void ejbActivate() {} public void ejbPassivate() {} }
package net.jibunstyle.hello.ejb; import java.rmi.RemoteException; import javax.ejb.CreateException; import javax.ejb.EJBHome; /** * Homeインタフェース */ public interface HelloHome extends EJBHome { public Hello create() throws RemoteException, CreateException; }
WARの構造
WAR(Web Application Archive)は下記のようなディレクトリ構造を持つZIPファイル。web.xmlファイルやlibディレクトリ、classesディレクトリが含まれるWEB-INFディレクトリ、JSPやHTMLなどのコンテンツファイルで構成される。
/ WEB-INF/ web.xml weblogic.xml lib/ classes/ net/ jibunstyle/ hello/ servlet/ HelloServlet.class hello.jsp
web.xmlファイルにはWARに含まれるServletの定義と、そのServletにアクセスするためのURLマッピング情報などを記載する。
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <servlet> <servlet-name>HelloServlet</servlet-name> <servlet-class>net.jibunstyle.hello.servlet.HelloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> </web-app>
weblogic.xmlファイルはWebLogic用のweb.xmlファイル。特に何も記載しなくてもよい。
<?xml version="1.0" encoding="ISO-8859-1"?> <weblogic-web-app> </weblogic-web-app>
libディレクトリには参照する共通ライブラリを、classesディレクトリにはServletのclassファイルを格納する。以下、ServletとJSPのソース。
package net.jibunstyle.hello.servlet; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.util.Properties; import javax.naming.Context; import javax.naming.InitialContext; import net.jibunstyle.hello.ejb.*; public class HelloServlet extends HttpServlet { public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Properties prop = new Properties(); String msg = ""; prop.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory"); prop.put(Context.PROVIDER_URL, "t3://localhost:8001"); Context ctx = null; try { ctx = new InitialContext(prop); } catch (Exception ex) { ex.printStackTrace(); } HelloHome home = null; Hello hello = null; try { home = (HelloHome)ctx.lookup("Hello"); } catch (Exception ex) { ex.printStackTrace(); } try { hello = home.create(); } catch (Exception ex) { ex.printStackTrace(); } String to = request.getParameter("to"); try { msg = hello.say(to); } catch (Exception ex) { ex.printStackTrace(); } request.setAttribute("to", to); request.setAttribute("result", msg); request.getRequestDispatcher("hello.jsp").forward(request, response); } }
<html> <head> <title>Hello Enterprise Application</title> </head> <body> <h1>Hello Enterprise Application</h1> <form action="/hello/hello" method="POST"> <div>Say hello to ... <input type="text" name="to" value="<%= request.getAttribute("to") %>"></div> <div><input type="submit" value="Say"> <div>Result : <%= request.getAttribute("result") %></div> </form> </body> </html>
EARのデプロイ(WebLogic)
できあがったEARファイルをWebLogicのautodeployフォルダにドロップすれば簡単にデプロイされる。あらかじめConfiguration Wizardで適当に作成した新しいドメインmydomainにデプロイする。autodeployディレクトリの場所は以下。
C:\bea\user_projects\domains\mydomain\autodeploy
動作確認
Webブラウザを起動して、 http://localhost:8001/hello/hello.jsp にアクセスする。なお、ポートはmydomain作成時に8001を指定した。
WebLogicに関する注意
まとめ
今までIDEにやらせていて詳しく理解できていなかった部分がクリアになった気がした。
おまけ
作業ディレクトリ構成とバッチファイル。なお、JRockitのbinディレクトリにパスが通っている前提で書かれている。
myear │ hello.ear │ ├─hello.ear.folder │ │ hello.jar │ │ hello.war │ │ mkear.bat │ │ │ ├─hello.jar.folder │ │ │ mkjar.bat │ │ │ │ │ ├─META-INF │ │ │ ejb-jar.xml │ │ │ weblogic-ejb-jar.xml │ │ │ │ │ └─net │ │ └─jibunstyle │ │ └─hello │ │ └─ejb │ │ Hello.class │ │ HelloBean.class │ │ HelloHome.class │ │ │ ├─hello.war.folder │ │ │ hello.jsp │ │ │ mkwar.bat │ │ │ │ │ └─WEB-INF │ │ │ web.xml │ │ │ weblogic.xml │ │ │ │ │ ├─classes │ │ │ └─net │ │ │ └─jibunstyle │ │ │ └─hello │ │ │ └─servlet │ │ │ HelloServlet.class │ │ │ │ │ └─lib │ └─META-INF │ application.xml │ weblogic-application.xml │ └─src │ buildejb.bat │ buildservlet.bat │ └─net └─jibunstyle └─hello ├─ejb │ Hello.java │ HelloBean.java │ HelloHome.java │ └─servlet HelloServlet.java
EJBビルド用(buildejb.bat)
@ECHO OFF SET CLASSPATH=C:\bea\weblogic92\server\lib\weblogic.jar SET DEST=..\hello.ear.folder\hello.jar.folder javac -d %DEST% net\jibunstyle\hello\ejb\*.java
サーブレットビルド用(buildservlet.bat)
@ECHO OFF SET CLASSPATH=C:\bea\weblogic92\server\lib\weblogic.jar;..\hello.ear.folder\hello.jar SET DEST=..\hello.ear.folder\hello.war.folder\WEB-INF\classes\ javac -d %DEST% net\jibunstyle\hello\servlet\*.java
hello.jar作成用(mkjar.bat)
jar -cf ..\hello.jar *
hello.war作成用(mkwar.bat)
jar -cf ..\hello.war *
hello.ear作成用(mkear.bat)
jar -cf ..\hello.ear *.jar *.war META-INF