レベル: 中級 中村 年宏 (nakamura.toshihiro@isid.co.jp)株式会社 電通国際情報サービス
2008年 05月 09日 連載の第 4 回目となるこの記事では、統合開発環境である WebSphere Application Server Toolkit と Seasar2 の HOT deploy 機能を利用して Web アプリケーションを快適に開発する方法を紹介します。
はじめに
WebSphere Application Server v6.1(以下 WAS)には、WebSphere Application Server Toolkit v6.1(以下 AST)と呼ばれる Eclipse をベースとした統合開発環境(IDE)が同梱されています。AST を利用すると、WAS 上で動作するアプリケーションの作成、テスト、およびデプロイが行えます。
AST には、アプリケーションの「自動公開」という機能があり、デフォルトで有効になっています。「自動公開」機能は、WAS 上で動作中のアプリケーションの Java コードが変更された場合に、その変更を感知し自動的にアプリケーションを更新(アプリケーションサーバーへ再デプロイ)します。この機能を利用することで、アプリケーションを手動で更新する手間を省くことができます。
ASTの「自動公開」は便利な機能ですが、Java コードの修正が開発時に何度も発生することを考えると、非効率な面もあります。まず、再デプロイには数秒から数十秒の待ち時間が発生するという問題があります。次に、再デプロイの結果、当然ながらアプリケーションの初期化情報やセッションの情報が失われてしまうという問題もあります。
Seasar2 では、バージョン 2.4 から HOT deploy と呼ばれる機能を搭載し、アプリケーションの再デプロイを行うことなく Java コードの修正を反映させることを可能にします。再デプロイが発生しないため、待ち時間の発生やセッション情報の喪失を防ぐことができます。この記事では、AST と Seasar2 の HOT deploy 機能を利用して Web アプリケーションを快適に開発する方法を紹介します。
HOT deploy
Seasar2 には、SMART deploy と呼ばれるコンポーネントをコンテナに自動登録するための機能があります。SMART deploy には複数のモードがあり、環境により最適なモードを選択できます。
SMART deploy の「deploy(デプロイ)」とは、Seasar2 のコンテナに Seasar2のコンポーネントを登録することを意味しています。AST の「自動公開」の説明の箇所で述べた「アプリケーションサーバーへの再デプロイ」という文脈で登場する「デプロイ」とは異なり、Web モジュール や EAR モジュールをアプリケーションサーバーへ配置するという意味ではありません。以降、この記事では、Seasar2 のコンポーネントの登録を意味する場合は SMART deploy などとアルファベットで表記し、モジュールのアプリケーションサーバーへの配置は「デプロイ」とカタカナで表記します。
HOT deploy は SMART deploy のモードのひとつで、Webアプリケーション開発専用のモードです。このモードでは、特別な仕組みにより、クラスをリクエストごとにロードし直します。そして、その結果、アプリケーションの再デプロイを行うことなく Java コードの修正を反映させます。
SMART deploy のモードには、HOT deploy 以外に、WARM deploy と COOL deploy があります。WARM deploy は単体テストやスタンドアロン環境のためのモード、COOL deploy は統合テストや運用環境のためのモードです。モードの切り替えは、設定ファイルで行えるようになっています。
HOT deployの仕組み
HOT deploy の仕組みは主に2つの要素で実現されています。それは、HOT deploy 専用のサーブレットフィルターとクラス・ローダーです。それぞれ、Seasar2 のライブラリに含まれる org.seasar.framework.container.hotdeploy.HotdeployFilter と org.seasar.framework.container.hotdeploy.HotdeployClassLoader というクラスです。
HotdeployFilter では次のことを行います。まず、リクエストを処理する前に、コンテキスト・クラス・ローダーに HotdeployClassLoader を設定します。次に、リクエストを処理するために後続の Filter を呼び出します。リクエストを処理後、コンテキスト・クラス・ローダーにセットされた HotdeployClassLoader を破棄します。
通常のクラス・ローダーは、委譲モデルに従ってクラスのロードを親クラス・ローダーに委ねますが、Seasar2 が提供する HotdeployClassLoader は、未ロードのクラスを親クラス・ローダーに委譲することなく自分自身でロードします。こうすることで、クラスがアプリケーションサーバーのクラス・ローダーにロードされることを防ぎます。アプリケーションサーバーにクラスがロードされてしまうと、クラスの修正を反映させるにはアプリケーションサーバーへの再デプロイが必要になってしまうからです。HotdeployClassLoader は、リクエストごとに生成・破棄されるため、クラスのロードはそのときの最新のクラスファイルから行われるようになります。これが、Java コードの修正を即座に反映させる HOT deploy の仕組みです。
コンポーネントの命名規約
HOT deploy を含め、SMART deploy を使用するには、Seasar2 が提供する命名規約に従う必要があります。これは、Seasar2 がコンポーネントの名前から実際のクラス名を特定するためです。命名規約は設定ファイル等でカスタマイズすることも可能です。
命名規約については、後ほどサンプルを解説する際にもう一度述べます。
AST の自動公開との違い
Seasar2 の HOT deploy と AST の自動公開の違いの最も大きな点は、アプリケーションの再デプロイが行われるかどうかです。ここでは、再デプロイの有無に伴う副次的な効果を含めてその違いを表に示します。
表 1. HOT deploy と自動公開の違い
|
| Seasar2 の HOT deploy | AST の自動公開 |
|---|
| アプリケーションの再デプロイ | なし | あり | | 修正を反映させるまでの待ち時間 | なし | 数秒から数十秒 | | アプリケーション初期化情報の喪失 | なし | あり | | セッション情報の喪失 | なし | あり | | 対象クラス | SMART deployの命名規約に従ったクラスとそのクラスで初めてロードされるクラス | 全クラス |
HOT deploy の対象となるクラスに制限があることに注意してください。たとえば、サーブレットフィルターから呼び出されるクラスを HOT deploy の対象にはできません。サーブレットフィルターのクラスはアプリケーションサーバーのクラス・ローダーにロードされ、Seasar2 の HotdeployClassLoader にロードされるわけではないからです。
サンプルアプリケーションの準備
AST を使って WAS 上で HOT deploy を行うサンプルを作成するために、環境を整えます。
動作環境
動作環境を示します。
次のプラットフォームを使用します。
- OS:Windows XP Professional SP2
- アプリケーションサーバー:WebSphere Application Server Network Deployment V6.1.0.15
- 統合開発環境:WebSphere Application Server Toolkit V6.1.1.6
Seasar プロジェクトで開発されている次のプロダクトを使用します。
- S2Container 2.4.25
- S2-Tiger 2.4.25
- Super Agile Struts 1.0.2-rc2
Web のフレームワークには、Super Agile Struts(以下 SAStruts)という Struts を拡張したフレームワークを使用します。SAStruts は Struts の弱点を補い、Struts の良いところをそのまま利用するフレームワークです。SAStruts は HOT deploy に完全対応しています。Java コードだけではなく、メッセージプロパティファイルの修正も直ぐに反映されます。
AST の設定
サンプルアプリケーションを作りやすくするために、次の設定を行います。
- 「テキスト・ファイル・エンコード」を UTF-8 に変更します。メニューの「ウィンドウ」-「設定」から設定ダイアログを開き、左側のツリービューから「一般」-「ワークスペース」を選択します。「テキスト・ファイル・エンコード」の項目で「その他」にチェックをつけ「UTF-8」を選択します。
図 1. ワークスペースの「テキスト・ファイル・エンコード」の設定
- JSP ファイルの「エンコード」を UTF-8 に変更します。メニューの「ウィンドウ」-「設定」から設定ダイアログを開き、左側のツリービューから「Web および XML」-「JSP ファイル」を選択します。「エンコード」の項目で「ISO 10646/ユニコード(UTF-8)」を選択します。
図 2. JSP ファイルの「エンコード」の設定
サーバーの作成と設定
サーバーを作成し、設定を行います。
- サーバーを作成します。メニューから「ファイル」-「新規」-「その他」を選択してダイアログを開き、「サーバー」を選択します。ダイアログを進めサーバーを作成します。この設定を行うには、あらかじめ WAS をインストールしておく必要があります。
- サーバーの設定を行います。メニューから「ウィンドウ」-「ビューの表示」-「その他」を選択し、サーバービューを開きます。ビューに表示されたサーバーをダブルクリックして「サーバーの概要」ページを開き、「自動公開しない」にチェックをします。また「サーバーをワークスペース内のリソースで実行する」がチェックされていることを確認します。これらの設定はHOT deploy を利用するために必要です。
図 3. サーバーの自動公開の設定
Web コンテナーのカスタムプロパティの設定
サーブレットフィルターをすべてのファイルにマッピングできるように WAS のWebコンテナーにカスタムプロパティを設定します。
- まず、サーバービューよりサーバーを起動させます。次に、サーバーを右クリックし「管理コンソールの実行」を選択します。「管理コンソール」が AST 内のブラウザに表示されたらログインし、「サーバー」-「アプリケーションサーバー」-「Webコンテナー」-「カスタム・プロパティー」と進みます。「カスタム・プロパティー」の画面で新規ボタンを押し、名前に
com.ibm.ws.webcontainer.invokefilterscompatibility、値に true と指定し適用ボタンを押します。
図 4. カスタムプロパティの設定
SAStruts を利用する動的 Web プロジェクトの作成
必要な jar ファイルや設定ファイルは、SAStruts のサイト からダウンロードできる sa-struts-blank-1.0.2-rc2.zip に含まれるものを使用します。sa-struts-blank-1.0.2-rc2.zip は解凍し、任意のフォルダに展開してください。ここでは展開先フォルダを「sa-struts-blank」と呼びます。
- 動的 Web プロジェクトを作成します。プロジェクト名は sample とします。「ターゲット・ランタイム」には、上記で作成したサーバーを指定します。「EARにプロジェクトを追加」のチェックボックスにチェックがされていることと「EAR プロジェクト名」が sampleEAR であることを確認してください。
図 5. 動的 Web プロジェクトの作成
- sa-struts-blank の
webapp\WEB-INF\lib フォルダ直下に含まれる jar ファイルを sample プロジェクトの WebContent/WEB-INF/lib フォルダにコピーします。ただし、geronimo-jta_1.1_spec-1.0.jar はコピーしないでください。理由は、この連載の第 1 回目 で述べたとおりです。
- sa-struts-blank の
webapp\WEB-INF フォルダの struts-config.xml と validator-rules.xml を sample プロジェクトの WebContent/WEB-INF フォルダにコピーします。web.xml は、ファイルごとコピーせず、以下のコードを sample プロジェクトの WebContent/WEB-INF/web.xml の display-name 要素と welcome-file-list 要素の間にコピーします。
リスト 1. web.xmlの一部
<filter>
<filter-name>encodingfilter</filter-name>
<filter-class>
org.seasar.extension.filter.EncodingFilter
</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter>
<filter-name>s2filter</filter-name>
<filter-class>
org.seasar.framework.container.filter.S2ContainerFilter
</filter-class>
</filter>
<filter>
<filter-name>hotdeployfilter</filter-name>
<filter-class>
org.seasar.framework.container.hotdeploy.HotdeployFilter
</filter-class>
</filter>
<filter>
<filter-name>routingfilter</filter-name>
<filter-class>
org.seasar.struts.filter.RoutingFilter
</filter-class>
<init-param>
<param-name>jspDirectAccess</param-name>
<param-value>false</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingfilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>s2filter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>hotdeployfilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>routingfilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>
org.apache.struts.action.ActionServlet
</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>configFactory</param-name>
<param-value>org.seasar.struts.config.S2ModuleConfigFactory</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>s2container</servlet-name>
<servlet-class>
org.seasar.framework.container.servlet.S2ContainerServlet
</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>s2container</servlet-name>
<url-pattern>/s2container</url-pattern>
</servlet-mapping>
|
- sa-struts-blank の src\main\resources フォルダ以下を sample プロジェクトの src フォルダにコピーします。コピー後、コピーした convention.dicon を開き、ルートパッケージ名を sample とします。
リスト 2. convention.dicon の修正
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN"
"http://www.seasar.org/dtd/components24.dtd">
<components>
<component class="org.seasar.framework.convention.impl.NamingConventionImpl">
<initMethod name="addRootPackageName">
<arg>"sample"</arg>
</initMethod>
</component>
<component
class="org.seasar.framework.convention.impl.PersistenceConventionImpl"/>
</components>
|
ルートパッケージ名とは、SMART deploy の対象のクラスが属するパッケージを束ねるパッケージの名称です。このパッケージの直下にあらかじめ定められた名前のパッケージを置き、そのパッケージに命名規約に従った名前のクラスを置くと、そのクラスは SMART deploy の対象になります。ルートパッケージの直下に置かれる代表的なパッケージ名には、action、logic、dao といったものがあります。また、クラスの命名規約には、サフィックスにパッケージ名の先頭一文字を大文字にしたものを使用するといったものがあります。たとえば、sample.action パッケージに置くクラスの名前を、XxxAction にします(ここで Xxx に相当する部分は任意の名称)。今回作成するサンプルでは action パッケージにクラスを作成し動作を確認します。
サンプルアプリケーションの作成と実行
入力した文字列をそのまま表示するという簡単なアプリケーションを作成します。HOT deploy で Java コードの修正が即座に反映されることを確認するために、WAS を起動させた状態で作成を進めます。
WAS の起動
サーバーが起動中の場合は、一旦停止してください。サーバーを選択し「プロジェクトの追加および除去」を選択し、開いたダイアログで sampleEAR プロジェクトを追加します。その後、サーバーを起動します。
JSP と Java クラスの作成
- sample プロジェクトの WebContent フォルダの下に echo フォルダを作成し、その直下に
echo.jsp を作成します。echo.jsp には次に示すコードを記述します。
リスト 3. WebContent/echo/echo.jsp
<%@page pageEncoding="UTF-8"%>
<%@taglib prefix="html" uri="http://struts.apache.org/tags-html"%>
<%@taglib prefix="s" uri="http://sastruts.seasar.org"%>
<%@taglib prefix="f" uri="http://sastruts.seasar.org/functions"%>
<html>
<head>
<title>Echo</title>
</head>
<body>
<html:errors/>
<s:form action="/echo">
<html:text property="arg"/>
<input type="submit" name="submit" value="サブミット"/>
<br />${f:h(result)}
</s:form>
</body>
</html>
|
-
sample.action パッケージを作成し、その直下に EchoAction.java を作成します。EchoAction クラスは、echo.jsp に対応するクラスです。
リスト 4. sample.action.EchoAction
package sample.action;
import org.seasar.struts.annotation.Execute;
public class EchoAction {
public String arg;
public String result;
@Execute(validator = false)
public String index() {
return "echo.jsp";
}
@Execute(validator = false)
public String submit() {
result = arg;
return "echo.jsp";
}
}
|
サンプルアプリケーションの実行
実行するには http://localhost:9080/sample/echo/ にアクセスしてください。この URL にアクセスすると、EchoAction クラスの index メソッドが呼び出され、echo.jsp にフォワードされます。SAStruts では、デフォルトで JSP の直接アクセスを禁じているため、初期画面を表示させるためには、このように index メソッド経由で JSP にアクセスするのが推奨の方法です。
ブラウザにはテキストボックス 1 つとボタンが 1 つのシンプルな画面が表示されます。
画面が表示されない場合は設定が間違っている可能性があります。次の点を確認してください。
-
convention.dicon のルートパッケージ名に sample と指定しているか?
-
EchoAction クラス が sample.action パッケージに存在するか?
- 管理コンソールから Web コンテナーのカスタムプロパティを設定したか?
HOT deploy の確認
表示された画面のテキストボックスに何らかの文字を入れてサブミットボタンを押すと、その値がそのままテキストボックスの下に表示されます。SAStruts は、サブミットボタンの name 属性の値と、Action クラスのメソッドを対応付けます。ここでは、 サブミットボタンの name 属性の値が submit なので、サブミットボタンが押された場合に EchoAction クラスの submitメソッドが実行されます。このメソッドでは入力値 arg を 出力値 result に代入し、フォワード先である echo.jsp という文字列を返します。フォワードされた echo.jsp では result の値を テキストボックスの下に表示します。
図 6. サンプルの実行結果
ここで、EchoAction クラスの submit メソッドを変更し、入力された文字を角括弧で囲んで表示するようにしてみます。次の修正を加えてください。
リスト 5. 修正を加えた sample.action.EchoAction クラスの submit メソッド
@Execute(validator = false)
public String submit() {
result = "[" + arg + "]";
return "echo.jsp";
}
|
このとき、アプリケーションの再デプロイは行われないはずです。再デプロイが行われたかどうかは AST のコンソールに出力されるログから判断してください。再デプロイが行われると、 プロジェクトのビルドの際にアプリケーションの停止や起動のログが出力されます。再デプロイが行われてしまった場合は、サーバーの設定で「自動公開」機能が無効になっているか確認してください。
修正が HOT deploy により反映されることを確かめるには、サブミットボタンを押します。入力された文字が角括弧で囲まれて出力されれば成功です。
図 7. サンプルの実行結果(修正後)
ここでは、サンプルとしてごく簡単な例を示しましたが、もっと大胆な修正をしても HOT deploy は有効に動作します。たとえば、クラスを新規に作成し、そのクラスを EchoAction クラスから呼び出すようにしても問題ありませんし、EchoAction クラスに新たなメソッドを追加しても問題ありません。
最後に
AST と Seasar2 の HOT deploy を利用して Web アプリケーションを快適に開発する方法を紹介しました。なお、サンプルで使用した SAStruts ですが、機能については詳しく触れませんでした。興味のある方は、参考文献に示した Super Agile Struts のサイトを参照してください。
参考文献
著者について  | |  | IBM AS/400 の RPG 言語を使ったプログラミングを経験して以来、データベースアクセス技術に興味を持つ。Seasar2 プロジェクトでは、S2Daoや Kuina-Dao などデータベースアクセスを簡単に行うためのプロダクトを中心にコミッタを務めている。 |
記事の評価
|