HomeDocumentation > 4. Apache Geronimo への移行 > 4.6. JBoss to Geronimo - Hibernate の移行
{scrollbar}

top
この文章は、Hibernate 3.2 を ORM ツールとして利用するアプリケーションを JBoss アプリケーション・サーバー 4.2.1 から Apache Geronimo 2.0 へ移行する手助けとなります。 

Hibernate は強力な、高性能なオブジェクト・リレーショナルの永続化とクエリー・サービスです。データベースのフィールドに結びつけられた属性の getter と setter メソッド持つ永続化(POJO)クラスの開発の助けになります。関連・継承・ポリモーフィズム・コンポジション・コレ クションなどのオブジェクト指向の特徴に従うことになります。Hibernate は、ネイティブな SQL、オブジェクト指向検索条件、例示 API などと同じように、移行可能な SQL 表現(HQL)を用いて検索を表現できます。

基本的には、Hibernate は Java クラスとデータベースの表を結びつけます。また、データ検索や検索機構によって、開発時間の短縮につながります。自然と、Java 中間層におけるオブジェクト指向のコード開発ができます。Hibernate のユニークな特徴は、MySQL、Oracle または DB2 など、どのようなデータベースにもアプリケーションが切り替えることができる透過的永続化機構です。Hibernate は Java Swing アプリケーション、Java サーブレット・アプリケーション、または EJB セッション・ビーンを利用するJ2EE アプリケーションなどに利用できます。(今回は、Java サーブレット・アプリケーションを利用します)

移行の手順を明らかにするために、最初にサンプル・アプリケーションを JBoss にデプロイし、その後 Geronimo へ移行します。サンプル・アプリケーションは、オンライン取引アプリケーションです。JDBC の移行手順の説明で既に利用した物です。このアプリケーションでは永続化のために Hibernate を利用するように変更します。

この文章には以下のセクションがあります。

Hibernate 実装の解析 implementation

Hibernate は以下のサービスを提供します。 

  • コネクション管理
  • トランザクション管理
  • オブジェクト・リレーションのマッピング

また、とても柔軟であり、さまざまなサービスと組み合わせて利用できます。JBoss、Geronimo ともトランザクション管理とコネクション管理機能を持っているので、この文章では hibernate を O/R マッピング機能のみ利用できるように構成します。一般的に、Hibernate はアプリケーション・サーバーと一緒に利用するように構成します。Hibernate はコネクション・プールの生成と環境の設定に構成ファイルである hibernate.cfg.xml を必要とします。このファイルにはデータベース・ドライバー、接続 url、SQL 方言(これは利用している RDBMS の仕様)、ユーザー名、パスワード、プールの大きさなどのパラメーターを含みます。また、*.hbm.xml というマッピング用ファイルの場所の定義も含みます。マッピング用ファイルはデータベースの表のフィールドと永続化クラスの属性とを結びつけるものです。

これらのプロパティは Apache Geronimo v2.0 を含めたアプリケーション・サーバーで一般的なものです。

しかし、JBoss(さらに言えば、Hibernate MBean)は、2つのさらなるデプロイメント機構を持っています。

一つ目は Hibernate  アーカイブ(HAR ファイル)です。これは Hibernate のすべてのクラスとマッピング・ファイルが含まれる特別なアーカイブである HAR ファイルです。JBoss はこのアーカイブを EAR や WAR ファイルと同じ方法でデプロイします。

もうひとつは、他のアプリケーションのクラスといっしょに、Hibernate のすべてのクラスとマッピング・ファイルを、例えば EAR の中に単にいれることです。Hibernate MBean は個別に構成され、マッピング・ファイルがアプリケーションのすべての JAR を探しかたを指定します。両方のデプロイメント機構とも、手作業で構成することなく、通常必要となるような設定コードを記述することなく、Hibernate オブジェクトをアプリケーションに追加することができます。

構造的には、HAR ファイルは JBoss サービス・アーカイブ(SAR ファイル)に似ています。HAR ファイルは Hibernate クラス・ファイルとマッピング・ファイル(*.hbm.xml)を、Hibernate アプリケーションが生成する必要がある Hibernate MBean の構成の定義を持つ標準の jboss-service.xml ファイルと一緒に保持します。最新の JBoss 製品では、hibernate-service.xml という名前にリネームされていますが、同じ構造と目的を持っています。

Hibernate アーカイブはトップレベルのパッケージとして、または EAR ファイルのコンポーネントとしてデプロイすることができます。Hbernate アーカイブは標準の J2EE デプロイメントの形式ではないので、これらをコンテキスト内で利用できるように EAR ファイルに jboss-app.xml ファイルを記述する必要があります。

以下の表はこれらアプリケーション・サーバーの機能ごとの比較です。

Feature

Apache Geronimo v2.0

JBoss v4.2.1

コンテナー管理データソース

サポートされています。Hibernate は与えられた JNDI 名のデータソースを利用することができます。アプリケーションと同じスレッドで実行されるからです。

サポートされています。Hibernate は与えられた JNDI 名のデータソースを利用することができます。

JNDI 自動バインディング

サポートされていません。

サポートされています。プロパティが設定されるとセッション・ファクトリーが JNDI コンテキストに結びつけられます。

JTA セッション・バインディング

この機能は導入直後そのままの状態ではサポートされていません。Geronimo トランザクション・マネージャーが利用できるようにルックアップを記述する必要があります。

導入直後からサポートされています。Hibernate は JBoss トランザクション・マネージャー向けのルックアップ・クラスを持っています。

JMX デプロイメント

導入直後そのままの状態ではサポートされていません。GBean と Hibernate コネクション・プロバイダー・クラスを記述すれば実装できます。

サポートされています。Hibernate は JBoss にデプロイできる org.hibernate.jmx.HibernateService を持っています。

Hibernate アーカイブ (HAR)

サポートされていません。Hibernate クラスは J2EE アーカイブの一部としてデプロイされます。

サポートされています。HAR は構成とマッピング・ファイルが含まれ、他のサーバーへのデプロイをサポートできるようになります。

キャッシング

hibernate のキャッシング機構を利用できます。

hibernate のキャッシング機構を利用できます。JBoss キャッシュもサポートされています。

セッション管理

サポートされていません。手動でセッションを開く必要があります。

Hibernate セッション・ライフサイクルは自動的に JTA トランザクションのスコープに結びつけることができます。手動でセッションを開いたり閉じたりする必要がなく、これは JBoss EBJ インターセプターが行います。

Hibernate マッピング・ファイル

Hibernate マッピング・ファイルの場所を指定する必要があります。

HAR デプロイを利用する場合は JBoss は自動的に Hibernate マッピング・ファイルを探しだします。

Back to Top

サンプル・アプリケーション sampleApp

この文章には、JBoss から Geronimo へアプリケーションの移行をデモンストレーションするサンプル・アプリケーションがあります。名前は Online Brokerage です。オンライン取引でユーザーが株の売買を行うシナリオです。このアプリケーションには以下の5つのページがあります。

  • Login ページ
  • Registration ページ
  • User Information ページ
  • Available Stocks ページ
  • User Portfolio ページ

以下の図は、アプリケーションのフローです。

最初に、ユーザーは Login ページに接続します。ログインページからユーザーはユーザー名とパスワードを入力します。ユーザー名またはパスワードが不正の場合は、アプリケーションは エラーメッセージを表示し、そのログインを拒否します。ユーザー名とパスワードが正確であれば、すべての株についてその時点の株価を見ることができる Available Stocks ページを開きます。
ユーザーは口座にある利用可能な金額に応じて、購入したい株を Buy ボタンをクリックすることで選択します。取引が無事完了すると、Available Stocks ページ が表示され、必要ならばさらに株が購入できます。株の購入に資金が不足していたら、アプリケーションはエラーとなり取引を進めません。エラーメッセージが Available Stocks ページの上部に表示されます。このページには User Info ボタンがあります。これをクリックすると、User Info ページが表示され、ユーザーの詳細情報が表示されます。
Available Stocks ページには、ユーザーが所有するすべての株を確認できる Portfolio へのリンクがあります。このページでは、ユーザーは株と株数を選んで売却することができます。また、User Cash 欄に現在の利用可能な現金の学が表示されています。所有している数より多くの株を売ろうとすると、アプリケーションはエラーになります。エラーメッセージ が同じページ上に表示されます。売却が成功すると、売却金額がユーザーの現金に加算されます。
quantity テキストボックスにはユーザーが持っている特定の会社の株の数量が表示されています。Quantity to Sell 欄では、その会社の株の売りたい数量を入力することができます。売却と購入にはラジオボタンをチェックします。このことは数値を入力した後になされます。 もし quantity to sell テキストボックスが入力されていないか、ラジオボタンがチェックされずに sell ボタンを押すと、必須入力欄が空であるという JavaScript のアラートが表示されます。数量欄に数値以外の文字が入っていると、別のアラートが表示されます。この動き方は、Available Stocks Page と同じようなものです。
新規ユーザーは、login ページで Register ボタンをクリックすることで登録できます。Registration ページでは、ユーザーID、ユーザー名、パスワード、住所と利用可能現金を入力することができます。
Back to Top


アプリケーション・クラスと JSP ページ

オンライン取引サンプル・アプリケーションには、以下のパッケージが含まれます。

  • com.dev.trade.bo
    • Stock - 会社の株を表す
    • User - ユーザーを表す
    • UserStock - ユーザーの所有する株を表す
  • com.dev.trade.dao
    • TradeDAO - すべてのデータベース接続メソッドを含む
  • com.dev.trade.exception
    • DBException - すべてのデータベースの例外を発生させるカスタム例外
  • com.dev.trade.servlet
    • TradeDispatcherServlet - すべてのリクエストを、要求されたデータベース機能を実行した後に JSP へ送る処理

オンライン取引には、以下の JSP ページを含みます。

  • login.jsp - アプリケーションのログインページ
  • error.jsp - アプリケーションのデフォルトのエラーページ
  • register.jsp - ユーザー登録のページ
  • stocks.jsp - ユーザーが株を購入できる Available Stocks ページ
  • userstocks.jsp - ユーザーの保持する株を表示する portfolio ページで、ユーザはここで株を売却する

Back to Top

利用するツール

オンライン取引アプリケーションの開発とビルドのツールは以下の通りです。

Apache Ant

Ant はピュア Java のビルド・ツールです。war ファイルをビルドし、オンライン取引アプリケーション向けデータベースを作成するために利用されています。Ant は以下の URL からダウンロードできます。

http://ant.apache.org

Hibernate

この文章を書いている時点では Hibernate 3.2 が最新の利用可能バージョンです。以下の URL からダウンロードできます。
http://www.hibernate.org

Hibernate に関する他の文章は、以下の URL にあります。
http://hibernate.org/5.html
http://www.hibernate.org/hib_docs/v3/reference/en/html/tutorial.html

Hibernate をダウンロードし、インストールしてください。インストールしたディレクトリーを後ほど <hibernate_home> として参照します。

Back to Top

サンプル・データベース

このアプリケーションのデモンストレーションに利用するデータベースは MySQL です。サンプル・データベース名は adi です。STOCKS、USERS、USERSTOCKS の3つのテーブルも持ちます。各テーブルは以下のフィールドを持ちます。

Table Name

Fields

STOCKS

ID (PRIMARY KEY)
NAME
PRICE

USERS

USERID (PRIMARY KEY)
NAME
PASSWORD
ADDRESS
CASH

USERSTOCKS

ID (PRIMARY KEY)
USERID (PRIMARY KEY)
NAME
PRICE
QUANTITY

USERSTOCKS テーブルは、各ユーザが所有する株を保存するために利用されます。USER と STOCKS テーブルはユーザーと株の詳細情報を保存するために利用されます。これは単にサンプル・アプリケーションですので、ユーザーの持つ金額の量は、ユーザー登 録時にユーザー自身に入力してもらいます。

このデータベース生成用の DDL は db.sql です。<brokerage_homge>\sql ディレクトリーにあります。

Back to Top

JBoss 環境 JBoss

このセクションでは、サンプルの JBoss 環境がどのように、どこにインストールされるかを示すので、貴方はこのシナリオを貴方の実装に合わせることができます。

JBoss のインストール、構成と管理の詳細な説明については、JBoss のドキュメントにあります。JBoss のウェブ・サイトで最新のドキュメントをチェックしてください。

以下のリストはインストールと初期環境の構成を完了させ、サンプル・アプリケーションのデプロイの準備を完了させるまでに必要な一般的なタスクを示します。

  1. 製品の説明書にしたがって、JBoss v4.2.1 をダウンロード、インストールしてください。以下、インストール・ディレクトリーを <jboss_home> として参照します。
  2. デフォルトの JBoss v4.2.1 アプリケーション・サーバーのコピーを作ってください。<jboss_home>\server\default ディレクトリーを再帰的に <jboss_home>\server\<your_server_name> へコピーしてください。
  3. <jboss_home>\bin ディレクトリーで run.sh -c <your_server_name> コマンドを入力し、新しいサーバーを始動してください。
  4. サーバーが始動すると、実行中かどうかの確認はウェブ・ブラウザーで http://localhost:8080を開くことでできます。JBoss Welcome ウィンドウが表示され、JBoss コンソールへ接続することができます。
  5. アプリケーション・サーバーが起動し、実行されたら、次はサンプル・アプリケーションに必要なソフトウェアをインストールし、構成するステップです。このステップは以下のセクションで説明します。

事前に必要なソフトウェアのインストールと構成

この文章でのオンライン取引アプリケーションのビルドと実行のために、ビルド・ツールとアプリケーションが利用するデータベースをインストールし、構成する必要があります。

データベースのインストール

前述のとおり、このアプリケーションは MySQL データベースを利用しています。次の URL からダウンロードできます。

http://www.mysql.com

メモ:貴方の持つ MySQL のバージョンに応じて、MySQL Connector/J のふさわしいバージョン (3.1、5.0、5.1) もダウンロードしてください。

この MySQL コネクターは <JBOSS_HOME>/server/default/lib に置いてください。

MySQL のインストールと構成は、かなり直感的です。MySQL リファレンス・マニュアルは次の URL からダウンロードできます。

http://dev.mysql.com/doc/mysql/en

メモ:簡単に構成するために、私はセキュリティ設定を変更し、root ユーザーに "password" というパスワードをつけました。このユーザー ID とパスワードは後ほどサンプル・アプリケーションからデータベースへ接続する際に利用されます。

サンプル・データベースの作成

MySQL のインスタンスが構成されたら、書庫アプリケーション(訳注:オンライン取引アプリケーションの間違い?)が利用するサンプル・データベースを作ります。コマンド・ラインから以下のコマンドを入力し、MySQL モニターを始動してください。

mysql -u root -ppassword

-p フラグとパスワードとの間にブランク文字がないことに注意してください。

MySQL コマンド・インターフェースが起動すると、以下のような表示になります。

solidMySQL monitor interface Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 7 to server version: 4.1.14-nt Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql>

MySQL コマンド・インターフェースから、以下のコマンドを入力し、adi サンプル・データベースを作成してください。

mysql> create database adi;

Ant の構成

前述のとおり、オンライン取引アプリケーションのビルドには Apache Ant を利用しています。もしまだ Ant をインストールしていなかったら、そろそろインストールして、 <ant_home>\bin ディレクトリーをシステムの path 変数に追加してください。

Apache Ant は以下の URL からダウンロードできます。

http://ant.apache.org

Hibernate の構成

JBoss には Hibernate が同梱されていますので、hibernate とは別に jar をダウンロードする必要はありません。 

Back to Top

サンプル・アプリケーションのビルド

この文章でのオンライン取引アプリケーションには、アプリケーションのビルドとデータベースの生成に利用できる Ant スクリプトが含まれています。サンプル・アプリケーションを次の URL からダウンロードしてください。Online Brokerage

zip ファイルを解凍すると、brokerage ディレクトリーが作られます。以下、このディレクトリーを <brokerage_home> とします。このディレクトリーで build.properties ファイルを開き、環境に合わせてプロパティを編集してください。以下に例を示します。

build.propertiessolid #Replace java.home with your jdk directory java.home=<java_home> #Replace jboss.home with the parent directory of lib/j2ee.jar jboss.home=<jboss_home>/server/<your_server_name> #Replace geronimo.home with the geronimo home directory. geronimo.home=<geronimo_home> #Fully qualified name of the JDBC driver class db.driver=com.mysql.jdbc.Driver #database url db.url=jdbc:mysql://localhost:3306/adi #database userId db.userid=root #database password db.password=password #script file for creating the tables sql.file=sql/db.sql #location of the jdbc driver jar. driver.classpath=<mysql-connector_home>/mysql-connector-java-3.1.14-bin.jar #location of the hibernate jars. dependency.dir=<hibernate_home>/lib

Hibernate の jar ファイルのパスが dependency.dir タグで定義されています。Geronimo と JBoss がそれぞれに Hibernate のコピーを持つ必要があることに注意してください。このディレクトリーに、<hibernage_home> ディレクトリーにある hibernate3.jar ファイルをコピーする必要があります。

重要: build.properties ファイルの driver.classpath を設定する際に、スラッシュ "/" を利用することに注意してください。そうしないとコンパイル・エラーになります。

コマンド・プロンプトやシェルで、<brokerage_home> ディレクトリーに移動して、ant コマンドを実行してください。そうすると、<brokerage_home>\jboss-artefact ディレクトリーに war 、har 、ear ファイルをビルドします。ant によってビルドされた war は、JBoss 固有のデプロイメント・ディスクリプターである jboss-web.xml ファイルを WEB-INF ディレクトリーに含みます。HAR ファイルには JBoss 固有の hibernate-service.xml ファイルを META-INF ディレクトリーに含みます。EAR ファイルには JBoss 固有のデプロイメント・ディスクリプターである jboss-app.xml を含みます。これらのファイルについて、以下に例を示します。

xmlsolidjboss-web.xml <?xml version="1.0" encoding="UTF-8"?> <jboss-web> <context-root>/brokerage</context-root> <resource-ref> <res-ref-name>jdbc/HibernateDB</res-ref-name> <res-type>javax.sql.DataSource</res-type> <jndi-name>jdbc/HibernateDS</jndi-name> </resource-ref> </jboss-web>

resource-ref 要素は、web.xml ファイルにある jdbc/HibernateDB という名前で参照されているリソースと、今回の例での MySQL データ・ソース向けである java:jdbc/HibernateDS という JNDI 名のリソースとを結び付けるために利用されます。

xmlsolidhibernate-service.xml <?xml version="1.0" encoding="UTF-8"?> <server> <mbean code="org.jboss.hibernate.jmx.Hibernate" name="jboss.har:service=Hibernate"> <attribute name="DatasourceName">java:jdbc/HibernateDS</attribute> <attribute name="Dialect"> org.hibernate.dialect.MySQLDialect </attribute> <attribute name="SessionFactoryName"> java:/hibernate/BrokerageSessionFactory </attribute> <attribute name="CacheProviderClass"> org.hibernate.cache.HashtableCacheProvider </attribute> <!-- <attribute name="ScanForMappingsEnabled">true</attribute> --> <attribute name="ShowSqlEnabled">true</attribute> </mbean> </server>

このファイルには設定する必要のある hibernate のプロパティを含んでいます。これらの名称と機能は次のとおりです。

  • DatasourceName - Hibernate が利用するデータ・ソースの JNDI 名です。
  • Dialect - 利用する SQL 方言です。
  • SessionFactoryName - セッション・ファクトリーの JNDI 名です。
  • CacheProviderClass - キャッシュ・プロバイダーのクラスです。
  • ShowSqlEnabled - 実行された SQL 文を出力します。

hibernate-service.xml ファイルは EAR(訳注:原文は EAR ですが、HAR では?)の META-INF ディレクトリーの中にあります。

xmlsolidjboss-app.xml <!DOCTYPE jboss-app PUBLIC "-//JBoss//DTD J2EE Application 1.4//EN" "http://www.jboss.org/j2ee/dtd/jboss-app_4_0.dtd"> <jboss-app> <module> <har>brokerage.har</har> </module> </jboss-app>

jboss-app.xml ファイルは EAR ファイルの META-INF ディレクトリーの中にあり、har ファイルの名前を記述しています。

以下の例ではこのアプリケーションで利用しているデプロイメント記述である web.xml を示します。web.xml ファイルは brokerage.war ファイルの WEB-INF ディレクトリーにあるデプロイメント記述で、サーブレット名やアプリケーションのデフォルトの JSP などについて記述されています。

xmlsolidweb.xml <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" version="2.4" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>brokerage</display-name> <servlet> <display-name>Trade-Dispatcher</display-name> <servlet-name>TradeDispatcher</servlet-name> <servlet-class>com.dev.trade.servlet.TradeDispatcherServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>TradeDispatcher</servlet-name> <url-pattern>/login</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>TradeDispatcher</servlet-name> <url-pattern>/stocks</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>TradeDispatcher</servlet-name> <url-pattern>/userstocks</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>TradeDispatcher</servlet-name> <url-pattern>/buy</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>TradeDispatcher</servlet-name> <url-pattern>/sell</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>TradeDispatcher</servlet-name> <url-pattern>/register</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>/login.jsp</welcome-file> </welcome-file-list> <error-page> <exception-type>javax.servlet.ServletException</exception-type> <location>/error.jsp</location> </error-page> <resource-ref> <res-ref-name>jdbc/HibernateDB</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> <res-sharing-scope>Shareable</res-sharing-scope> </resource-ref> </web-app>

Back to Top

サンプル・データの生成

前述のとおり、db.sql スクリプトがサンプル・データを生成します。このファイルの場所はすでに build.properties 内で sql.file タグによって定義されています。サンプル・データの生成には、単に <brokerage_home> ディレクトリーで以下のコマンドを実行してください。

ant populateDB

Back to Top

サンプル・アプリケーションのデプロイ

サンプル・アプリケーションをデプロイする前に、このアプリケーションが必要とするデータ・ソースを構成する必要があります。JBoss でデータ・ソースの構成をデプロイするには、<brokerage_home>\plan ディレクトリーにある mysql-ds.xml ファイルを以下のディレクトリーにコピーしてください。

<jboss_home>\server\<your_server_name>\deploy

データベースのデプロイと同様に、JBoss でのオンライン取引アプリケーションのデプロイは、Ant でビルドした brokerage.ear ファイルを以下のディレクトリーにコピーしてください。

<jboss_home>\server\<your_server_name>\deploy

もし JBoss がすでに始動していたら、自動的にアプリケーションがデプロイされ、始動されます。そうでなければ、アプリケーションは次回始動時にデプロイされ、始動されます。 

Back to Top

サンプル・アプリケーションのテスト

アプリケーションをテストするには、ウェブ・ブラウザーを開き、以下の URL に接続してください。

http://localhost:8080/brokerage

オンライン取引アプリケーションのログイン画面が表示されます。user name 欄に j2ee 、password 欄に password を入力し、login をクリックしてください。以下の図のような available stocks ページが表示されます。アプリケーションは構成され、実行されています。
Back to Top

Geronimo 環境 Geronimo

以下の URL から Geronimo をダウンロードし、インストールしてください。

http://geronimo.apache.org/downloads.html

そこにあるリリース・ノートには、システム要件とインストール、始動方法がが明示されています。以下、この文章では Geronimo のインストール・ディレクトリーを <geronimo_home> とします。

Back to Top

リソースの構成

Geronimo でオンライン取引アプリケーションを実行するために、JBoss で利用したものと同じ MySQL データベース を利用します。Geronimo 環境に準備のためにするべき作業は、データ・ソースを構成するだけです。

データ・ソースの構成

データ・ソースのデプロイメント・プランで参照可能になるように、MySQL データベースのドライバーを Geronimo リポジトリーにコピーする必要があります。Geronimo リポジトリーは <geronimo_home>/repository ディレクトリにあります。このディレクトリーの中に mysql/jars というディレクトリーを作り、そこへ mysql-connector-java-3.1.14-bin.jar ファイルをコピーしてください。

データ・ソースのデプロイメント・プランを定義する必要があります。簡単になるように、サンプル・アプリケーションにはすでに mysql-geronimo-plan.xml というデプロイメント・プランが <brokerage_home>\plan ディレクトリーの中にあります。以下の例がデプロイメント・プランの中身です。

xmlsolidmysql-geronimo-plan.xml <?xml version="1.0" encoding="UTF-8"?> <connector xmlns="http://geronimo.apache.org/xml/ns/j2ee/connector-1.2"> <dep:environment xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.1"> <dep:moduleId> <dep:groupId>user</dep:groupId> <dep:artifactId>database-pool-HibernateDB</dep:artifactId> <dep:version>2.0</dep:version> <dep:type>car</dep:type> </dep:moduleId> <dep:dependencies> <dep:dependency> <dep:groupId>mysql</dep:groupId> <dep:artifactId>mysql-connector-java</dep:artifactId> <dep:version>3.1.14-bin</dep:version> <dep:type>jar</dep:type> </dep:dependency> </dep:dependencies> </dep:environment> <resourceadapter> <outbound-resourceadapter> <connection-definition> <connectionfactory-interface>javax.sql.DataSource</connectionfactory-interface> <connectiondefinition-instance> <name>HibernateDS</name> <config-property-setting name="Password">password</config-property-setting> <config-property-setting name="CommitBeforeAutocommit">false</config-property-setting> <config-property-setting name="Driver">com.mysql.jdbc.Driver</config-property-setting> <config-property-setting name="ExceptionSorterClass">org.tranql.connector.AllExceptionsAreFatalSorter</config-property-setting> <config-property-setting name="UserName">root</config-property-setting> <config-property-setting name="ConnectionURL">jdbc:mysql://localhost:3306/adi</config-property-setting> <connectionmanager> <local-transaction/> <single-pool> <max-size>10</max-size> <min-size>0</min-size> <blocking-timeout-milliseconds>5000</blocking-timeout-milliseconds> <idle-timeout-minutes>30</idle-timeout-minutes> <match-one/> </single-pool> </connectionmanager> </connectiondefinition-instance> </connection-definition> </outbound-resourceadapter> </resourceadapter> </connector>

デプロイメント・プランを作り、ドライバーをコピーしたら、次のステップは実際にデータ・ソースのコネクション・プールをデプロイすることです。もし Geronimo を始動していなければ、以下のコマンドで実行し、始動してください。

<geronimo_home>\bin\geronimo start

データ・ソースのコネクション・プールをデプロイするために、以下のコマンドを実行してください。 

<geronimo_home>\bin\deploy --user system --password manager deploy <brokerage_home>\plan\mysql-geronimo-plan.xml ..\repository\org\tranql\tranql-connector-ra\1.3\tranql-connector-ra-1.3.rar

環境によりますが、以下のような確認メッセージが表示されるでしょう。

#FFFFFFsolid C:\geronimo-2.0\bin>deploy --user system --password manager deploy \brokerage\plan\mysql-geronimo-plan.xml ..\repository\org\tranql\tranql-connector-ra\1.3\tranql-connector-ra-1.3.rar Deployed user/database-pool-HibernateDS/2.0/car

Back to Top

ステップ・バイ・ステップの移行migration

Apache Geronimo はHARアーカイブ形式をサポートしていないので、今回は全てのクラスをWARアーカイブの中に格納します。このアプリケーションをGeronimoで動かすためにクラスを2つ作成する必要があります。ひとつはGeronimo用のTransactionManagerLookupクラスで、もうひとつはセッション・ファクトリーを入手するためのユーティリティ・クラスHibernateUtilです。 それ以外にTradeDispatcherServlet とTradeDAOクラスに若干の変更を加える必要があります。

手始めに、アプリケーションに加えるべき変更点を下記のリストで眺めてみましょう。

#TradeDAO
#HibernateUtil
#TradeDispatcherServlet

TradeDAO TradeDAO

JBoss環境に於いては、HibernateMBeanがグローバルJNDIコンテキストへのセッション・ファクトリーを作成・バインドしてくれます。この機構により、単純なルックアップだけでセッション・ファクトリーを入手できるようになるわけです。セッションはセッション・ファクトリー経由で入手することができます。

}}{{{}TradeDAO.java<brokerage_home>/src/com/dev/trade/dao ディレクトリーに存在します。

javasolidExcerpt from TradeDAO.java for JBoss JBoss用のTradeDAO.javaの抜粋 package com.dev.trade.dao; import java.sql.Connection; import java.sql.SQLException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Set; import javax.naming.InitialContext; import javax.naming.NamingException; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import com.dev.trade.bo.Stock; import com.dev.trade.bo.User; import com.dev.trade.bo.UserStock; import com.dev.trade.exception.DBException; import com.dev.trade.util.HibernateUtil; public class TradeDAO { SessionFactory factory = null; Session session = null; public TradeDAO() throws Exception { try { InitialContext ctx = new InitialContext(); factory = (SessionFactory)ctx.lookup("java:hibernate/BrokerageSessionFactory"); } catch (NamingException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } public User getUserByUserId(String userId) throws DBException { session = factory.getCurrentSession(); Query q = session.createQuery("from User u where u.userId=:userId"); q.setString("userId", userId); return (User) q.uniqueResult(); } ...

Geronimo環境ではセッション・ファクトリーを作成するための新しいユーティリティ・クラス、HibernateUtil classを作成することになります。
このクラスには、セッションを入手するための getCurrentSession()メソッドがあります。

TradeDAO.java の冒頭の箇所を以下の抜粋に従って修正します。

javasolidExcerpt from TradeDAO.java for Geronimo Geronimo用のTradeDAO.javaの抜 package com.dev.trade.dao; import java.sql.Connection; import java.sql.SQLException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Set; import org.hibernate.Query; import org.hibernate.Session; import com.dev.trade.bo.Stock; import com.dev.trade.bo.User; import com.dev.trade.bo.UserStock; import com.dev.trade.exception.DBException; import com.dev.trade.util.HibernateUtil; public class TradeDAO { Session session = null; public TradeDAO() throws Exception { } public User getUserByUserId(String userId) throws DBException { session = HibernateUtil.getCurrentSession(); Query q = session.createQuery("from User u where u.userId=:userId"); q.setString("userId", userId); return (User) q.uniqueResult(); } ...

以下の文字列を探索・置換します。
factory.getCurrentSession()

HibernateUtil.getCurrentSession()
で置換します。

9箇所が置換されるはずです。

セッションを入手する方法が、Apache Geronimo上でアプリケーションを動かすためのコード上の相違点の代表的なものです。

HibernateUtil HibernateUtil

既に述べたとおり、このクラスはセッション・ファクトリーを作成し、アプリケーションにHibernateのセッションを提供するために使われます。このクラスのソース・コードは以下のようになります。

javasolidHibernateUtil.java for Geronimo package com.dev.trade.util; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.cfg.Configuration; /** * Configures and provides access to Hibernate sessions, tied to the * current thread of execution. Follows the Thread Local Session * pattern, see {@link http://hibernate.org/42.html}. */ public class HibernateUtil { /** location of the Hibernate Configuration File */ private static String CONFIG_FILE_LOCATION = "hibernate.cfg.xml"; /** Holds a single instance of Session */ private static final ThreadLocal threadLocal = new ThreadLocal(); /** The single instance of hibernate configuration */ private static final Configuration cfg = new Configuration(); /** The single instance of hibernate SessionFactory */ private static org.hibernate.SessionFactory sessionFactory; /** * Returns the ThreadLocal Session instance. Lazy initialize * the <code>SessionFactory</code> if needed. * * @return Session * @throws HibernateException */ public static Session getCurrentSession() throws HibernateException { Session session = (Session) threadLocal.get(); if (session == null || ! session.isConnected()) { if (sessionFactory == null) { try { cfg.configure(CONFIG_FILE_LOCATION); sessionFactory = cfg.buildSessionFactory(); } catch (Exception e) { System.err.println("%%%% Error Creating SessionFactory %%%%"); e.printStackTrace(); } } session = sessionFactory.openSession(); threadLocal.set(session); } return session; } /** * Close the single hibernate session instance. * * @throws HibernateException */ public static void closeSession() throws HibernateException { Session session = (Session) threadLocal.get(); if (session != null) { session.close(); } } }

HibernateUtil.java<brokerage_home>/src/com/dev/trade/util ディレクトリーに配置します。ご参考までに、このファイルのコピーは既にサンプル・アプリケーションと一緒に提供されています。

TradeDispatcherServlet TradeDispatcherServlet

このクラスにもセッション・ファクトリーを入手する際の相違点があります。JBossではセッション・ファクトリーの入手はJNDIコンテキスト経由で行いましたが、Geronimoではユーティリティ・クラス経由で行います。

javasoliddoGet method for JBoss JBoss用のdoGetメソッド protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Session hsession = null; try { InitialContext ctx = new InitialContext(); SessionFactory factory = (SessionFactory)ctx.lookup("java:hibernate/BrokerageSessionFactory"); hsession = factory.openSession(); } catch (NamingException e1) { e1.printStackTrace(); } Transaction tr = hsession.beginTransaction();

TradeDispatcherServlet.java は <brokerage_home>/src/com/dev/trade/servlet ディレクトリーに配置されています。doGetメソッドを以下の例に従って置換してください。

javasoliddoGet method for Geronimo protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Transaction tr = HibernateUtil.getCurrentSession().getTransaction(); tr.begin();

Hibernateは色々なアプリケーション・サーバーようにトランザクション・マネージャーのルックアップ用のクラスを提供しています。残念ながら、Hibernate 3.2はApache Geronimo用のルックアップ用クラスを提供していませんので、自分たちで作らなくてはなりません。Geronimo用のトランザクション・マネージャーのルックアップ・クラスのコードは以下のようになります。

javasolidGeronimoTransactionManagerLookup package org.hibernate.transaction; import java.util.Iterator; import java.util.Properties; import java.util.Set; import javax.transaction.TransactionManager; import org.hibernate.HibernateException; import org.hibernate.transaction.TransactionManagerLookup; import org.apache.geronimo.gbean.AbstractName; import org.apache.geronimo.gbean.AbstractNameQuery; import org.apache.geronimo.kernel.Kernel; import org.apache.geronimo.kernel.KernelRegistry; import org.apache.geronimo.kernel.proxy.ProxyManager; public class GeronimoTransactionManagerLookup implements TransactionManagerLookup { public static final String UserTransactionName = "java:comp/UserTransaction"; public TransactionManager getTransactionManager(Properties props) throws HibernateException { /* * try { Kernel kernel = KernelRegistry.getSingleKernel(); ProxyManager * proxyManager = kernel.getProxyManager(); AbstractNameQuery query = * new AbstractNameQuery(TransactionManager.class.getName()); Set names = * kernel.listGBeans(query); AbstractName name = null; for (Iterator it = * names.iterator(); it.hasNext();) name = (AbstractName) it.next(); * Object transMg = (Object) proxyManager.createProxy(name, * TransactionManager.class); return (TransactionManager)transMg; }catch * (Exception e) { e.printStackTrace(); System.out.println(); throw new * HibernateException("Geronimo Transaction Manager Lookup Failed", e); } */ try { Kernel kernel = KernelRegistry.getSingleKernel(); AbstractNameQuery query = new AbstractNameQuery(TransactionManager.class.getName ()); Set<AbstractName> names = kernel.listGBeans(query); if (names.size() != 1) { throw new IllegalStateException("Expected one transaction manager, not " + names.size()); } AbstractName name = names.iterator().next(); TransactionManager transMg = (TransactionManager) kernel.getGBean(name); return (TransactionManager)transMg; } catch (Exception e) { e.printStackTrace(); System.out.println(); throw new HibernateException("Geronimo Transaction Manager Lookup Failed", e); } } public String getUserTransactionName() { return UserTransactionName; } }

ご参考までに、このクラスは既に <brokerage_home>/TransactionManager ディレクトリーに配置されています。以下のようなディレクトリー構造を作り、そこに GeronimoTransactionManagerLookup.java をコピーしてください。

*brokerage_home>/src/org/hibernate/transaction

さて次にHibernateの構成ファイル hibernate-cfg.xml を作る必要があります。このファイルの中に必要なHibernateの構成上の属性を記述します。JBoss環境での hibernate-service.xml は hibernate-cfg.xml と同じ働きをしている点にご留意ください。ご参考までに、サンプルアプリケーションと共にこのファイルも既に <brokerage_home>/hibrenate ディレクトリーに提供されています。

xmlsolidhibernate-cfg.xml <?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- properties --> <property name="connection.datasource">java:comp/env/jdbc/HibernateDB</property> <property name="hibernate.transaction.manager_lookup_class"> org.hibernate.transaction.GeronimoTransactionManagerLookup </property> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <!-- Disable the second-level cache --> <property name="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</property> <property name="hibernate.current_session_context_class">org.hibernate.context.JTASessionContext</property> <!-- Echo all executed SQL to stdout --> <property name="hibernate.show_sql">true</property> <!-- Drop and re-create the database schema on startup --> <!--<property name="hibernate.hbm2ddl.auto">create</property> --> <!-- mapping files --> <mapping resource="Stock.hbm.xml"/> <mapping resource="UserStock.hbm.xml"/> <mapping resource="User.hbm.xml"/> </session-factory> </hibernate-configuration>

各々のプロパティ毎の詳細な機能説明についてはHibernareのマニュアルを参照してください。

ビルド前の最後のステップとして、Geronimo固有のデプロイメント記述子である geronimo-web.xml を作成します。以下の例を参照してください。またご参考までにこのファイルは <brokerage_home>/web/descriptors/geronimo ディレクトリーに既に提供されています。

xmlsolidgeronimo-web.xml <?xml version="1.0" encoding="ISO-8859-1"?> <web-app xmlns="http://geronimo.apache.org/xml/ns/j2ee/web-1.1" xmlns:naming="http://geronimo.apache.org/xml/ns/naming-1.1"> <dep:environment xmlns:dep="http://geronimo.apache.org/xml/ns/deployment-1.1"> <dep:moduleId> <dep:groupId>BrokerageApp</dep:groupId> <dep:artifactId>MySqlDS</dep:artifactId> <dep:version>2.0</dep:version> <dep:type>car</dep:type> </dep:moduleId> <dep:dependencies> <dep:dependency> <dep:groupId>user</dep:groupId> <dep:artifactId>database-pool-HibernateDB</dep:artifactId> <dep:version>2.0</dep:version> <dep:type>car</dep:type> </dep:dependency> </dep:dependencies> <dep:hidden-classes> <dep:filter>org.springframework</dep:filter> <dep:filter>META-INF/spring</dep:filter> <!--dep:filter>antlr</dep:filter--> </dep:hidden-classes> </dep:environment> <context-root>/brokerage</context-root> <resource-ref> <ref-name>jdbc/HibernateDB</ref-name> <resource-link>HibernateDS</resource-link> </resource-ref> </web-app>

<hidden-classes> エレメントは、warクラスローダーがクラス探索時にApache Geronimoの提供クラスを参照してしまうことで発生するかもしれないバーション不一致の問題を回避するための指定です。

Back to Top

サンプル・アプリケーションのビルド

サンプル・アプリケーションをビルドするには以下のコマンドを実行します。

  • hibernate jar をクラスパスに追加してください。GeronimoTransactionManagerLookup クラスはhibernate と共にビルドする必要があります。貴方がHibernateのソースコードをダウンロードしていないとしても、hibernate jarをクラスパスに追加すればクラスをコンパイルできるようになります。その後、コンパイルしたクラスをhibernate jarファイルに追加します。

set CLASSPATH=%CLASSPATH%;<hibernate_home>/lib/hibernate3.jar

  • クラスパスにgeronimoのカーネルを追加する
    set CLASSPATH=%CLASSPATH%;<geronimo_home>/lib/geronimo-kernel-2.0.1.jar
  • 今回のサンプルでは必要ありませんが、特定のクラスをご自分で追加するならお好みのツールを使って、GeronimoTransactionManagerLookup.classを <hibernate_home>/lib/hibernate3.jar ファイルの中の org\hibernate\transaction ディレクトリーに追加してください。
  • では以下のコマンドを使って移行されたアプリケーションをビルドしてみます。

<brokerage_home>/ant war

今回のオンライン仲介サンプル・アプリケーションは単なるWebアプリケーションなので war ターゲットを使っています。JBossのセクションではwarとharをパッケージするためにear形式を使いましたが、har形式はGeronimoではサポートされていません。

実行の結果、<brokerage_home>/geronimo-artefact ディレクトリーに brokerage.war ができます。

<brokerage_home>/solutions ディレクトリーにはコンパイルおよびGeronimo環境で稼動させるための移行済みのソースファイル類が含まれています。

Back to Top

移行したサンプル・アプリケーションのデプロイ

移行したオンライン仲介サンプル・アプリケーションをデプロイするには、Geronimoサーバーが起動して正常稼動していることを確認してから以下のコマンドを実行します。

deploy --user system --password manager deploy <brokerage_home>/geronimo-artefact/brokerage.war

アプリケーションがデプロイされたら、Webブラウザーを開いて以下のURLにアクセスしてください。
http://localhost:8080/brokerage

JBoss環境でアプリケーションをテストした時に使ったユーザー名、パスワードと同じものを指定してログインします。

Back to Top

サマリー summary

この記事ではO/Rマッピング層にHibernateを使っているサンプル・アプリケーションをJBossからApache Geronimoへ移行する方法を紹介しました。JBossで提供されている機能・フィーチャーの全てが現時点のGeronimoでは実装されているわでけはないので、結果的に若干の追加のコーディングが必要でしたが、全体的な移行の難易度は低いものでした。

Back to Top