レベル: 中級 Michael Galpin, Developer, eBay
2008年 7月 08日 皆さんは Web サイトを迅速かつ安価に構築したいと思う一方、産業レベルの実力を持った技術を活用したいと思っているのではないでしょうか。Grails と Apache Geronimo を使うことで、まさにそれを実現することができます。Grails は動的言語である Groovy の強力さを活用して開発を加速します。その一方で Grails は実証済みの Java 技術を活用して Java™ 仮想マシン上で実行されます。そのため、Apache Geronimo に Grails アプリケーションをデプロイすることで、そのアプリケーションを容易に次のレベルに高めることができます (Apache Geronimo は Java EE V5 に認定された、オープンソースの主要なアプリケーション・サーバーです)。この記事では、Grails によって Web 開発がいかに容易になるか、また Geronimo によって Grails のデプロイメントがいかに容易になるかを説明します。さらに Geronimo によって提供されるリソースやサービスを Grails アプリケーションがどのように活用するかについても説明します。
はじめに
この記事では、Grails を使って Web アプリケーションを作成し、それを Apache Geronimo にデプロイします。この記事の手順を追うためには以下のソフトウェアをインストールしておく必要があります。
- JDK (Java Development Kit)
- Grails も Geronimo も JDK を必要とします。Grails には Java V1.4 で十分ですが、Geronimo には V1.5 が必要です。これは Geronimo が Java EE V5 認定のアプリケーション・サーバーであり、Java EE V5 がアノテーションや Generics など、Java 1.5 の機能を必要とするためです。この記事では Java SE V1.6_05 を使います。
- Groovy プログラミング言語
- Grails は Groovy プログラミング言語を使いますが、Groovy は Grails に含まれているため、追加でダウンロードする必要はありません。また Grails は Hibernate や Spring など、最善の組み合わせの製品を数多く使いますが、それらの製品も Grails に含まれています。
- Grails
- この記事では Grails V1.0.2 を使います。
- Apache Geronimo
- この記事では Apache Geronimo V2.1.1 を使います。Geronimo としては Tomcat または Jetty のディストリビューションが使えますが、この記事では Jetty のディストリビューションを使います。
- MySQL
- この記事では MySQL V5.0.41 を使いますが、Hibernate でサポートされる任意のデータベースが使えるはずです。
この記事は Grails の入門記事ではありません。この記事を読むためには既に Grails について理解している必要がありますが、Ruby on Rails と Java を理解していれば、おそらく苦労なく読み進めるはずです。「参考文献」のセクションには、Grails についてよく理解するための参考となる優れた記事をいくつか挙げてあります。
Grails による広告ネットワーク
Grails と Geronimo とをどのように組み合わせて使うのかを示すために、Grails を使って簡単なアプリケーションを作成し、そのアプリケーションを Geronimo にデプロイして機能強化を行います。アプリケーションとしては、簡単な広告ネットワーク (ad network) を作成します。このアプリケーションのユース・ケースを大きく分けると次のように分解することができます。
- 広告主 (advertiser) はネットワークに登録することができます。必要なものは名前とパスワードのみです。
- 広告主はネットワークにログインすることができます。
- 広告主は広告を作成することができます。この広告には、タイトルとテキスト、それに画像の URL があります。またこの広告には、開始日と終了日、優先順位、そしてキーワードもあります。キーワードはその広告をいつ表示するかを決定し、優先順位は、複数の広告が同じキーワードを持つ場合の優先順を決めるために使われます。
- 会員 (affiliate) は Web サービスを呼び出して広告のリストを取得することができます。会員はキーワードと、広告の最大数を提供します。
これは非常に単純なアプリケーションです。Grails によるこの広告ネットワークは、とても Google や Yahoo! に取って代わるようなものではありませんが、この広告ネットワークを作成することによって Grails の魅力的な機能の多くを使ってみることができます。それではそうした機能をいくつか調べ、それらを使うことで Grails を使った広告ネットワーク・アプリケーションの開発がいかに迅速になるかを見てみましょう。
Grails は Convention over Configuration (設定より規約) の原則と DRY (Don't Repeat Yourself) の原則を活用することで、Web アプリケーションを作成する際に通常必要となるコードの量を大幅に削減しています。さらに、Grails のコード生成スクリプトをいくつか使用することで、開発作業を迅速に開始することができます。
アプリケーションを作成する
このアプリケーションを adserver と呼ぶことにしましょう。まず、Grails の generate-app コマンドを使って作業を開始します。このコマンドの動作に関しては、あまり時間をかけないことにします (このコマンドを知らない人は「参考文献」を参照してください)。重要なことは、アプリケーションが Grails の規約に従ってセットアップされていることです。これは Grails フレームワークがクラスや構成用のメタデータを探す場所を知るために重要なだけではなく、そうすることでアプリケーションのパッケージ化やデプロイメントがずっと容易になるのです。図 1 は、このディレクトリー構造の様子を示すスナップショットです。
図 1. adserver アプリケーションの構造
Grails では、ボトムアップの開発プロセスが推奨されています。ボトムアップの開発プロセスでは、通常はドメイン・モデルを定義することから始めます。そのためには Grails の create-domain-class コマンドを使います。最初に作成するモデルは Advertiser モデルです (リスト 1)。
リスト 1. Advertiser クラス
class Advertiser {
static hasMany = [ads:Ad]
String name
String password
}
|
Grails や Groovy 全般に関して慣れている人であれば想像できるとおり、このクラスは非常に単純です。ここで最も複雑な部分は hasMany の行です。この行は、Advertiser が複数の Ad を持てることを示しています。ではこの Ad クラスを見てみましょう。
リスト 2. Ad クラス
class Ad {
static belongsTo = [advertiser:Advertiser]
String title
String imageUrl
String text
String keywords
Date startDate
Date endDate
Integer bid
}
|
このクラスも非常に単純であり、Advertiser クラスとの 1 対多の関係の多側になります。今度は Grails の generate-all スクリプトを使って、これらのクラスそれぞれに対して scaffold コード (すべての CRUD アクションに対するコントローラー・クラスと GSP (GNU Server Pages) ビュー) を作成し、run-app コマンドを使ってアプリケーションを実行します。この方法はオプションですが、Grails が初めての人にとっては特に便利です。これはドメイン・クラスの使い方の好例であると同時に、コントローラーとビューの作成方法の好例でもあります。アプリケーションのコントローラーとビューをカスタマイズする場合には、この方法を知っている必要があります。
アプリケーションをカスタマイズする
最初に必要なことは、ユーザー (advertiser: 広告主) の登録ができるようにすることです。そのために RegisterController を作成します。このコードをリスト 3 に示します。
リスト 3. RegisterController
class RegisterController {
def index = { }
def save = {
def exists = Advertiser.findWhere(name:params.name)
if (exists){
flash.message = "The name " + params.name + " is already taken"
redirect(action:index)
}
def advertiser = new Advertiser()
advertiser.properties = params
advertiser.save(flush:true)
session.advertiser=advertiser
redirect(controller:"ad",action:"adsFor")
}
}
|
ここで行われていることの中心は、advertiser が選択した名前が既に使われていないかどうかをチェックすることです。その名前が使われている場合には、エラー・メッセージを作成し、index ページにリダイレクトします。まだその名前が使われていない場合には、その advertiser が作成されます。ここではセッションに Advertiser インスタンスを格納しているため、Advertiser インスタンスを再度参照する必要はなく、Ad コントローラーにリダイレクトしています。このクラスについてはこのすぐ後に調べますが、まず advertiser がログインできるようにする必要があります。Login コントローラーをリスト 4 に示します。
リスト 4. Login コントローラー
class LoginController {
def index = { }
def login = {
def advertiser = Advertiser.findWhere(
name:params.name , password:params.password )
if (!advertiser){
flash.message = "The password does not match the name of the advertiser"
redirect(action:index)
}
session.advertiser=advertiser
redirect(controller:"ad",action:"adsFor")
}
}
|
これも単純な Groovy クラスです。このクラスはデータベース内に名前とパスワードが両方一致するものが含まれているかどうかをチェックします。一致するものがある場合にはセッションに advertiser をセットし、先ほど Register コントローラーの中で見たのと同じ Ad コントローラーの同じアクションに転送します。Ad コントローラーに移る前に、これらのコントローラー・メソッドがドメイン・オブジェクトのデータ・アクセス・コードを直接使用していることに気付いた人がいるかもしれません。これに代わる方法としては、サービス・レイヤーを使います。
Grails のサービス・レイヤー
この場合のベスト・プラクティスは、RegisterController と LoginController の中にあった Advertiser.findWhere コードをサービス・レイヤーに移してしまうことです。そのためには Grails の create-service コマンドを使ってコードをリファクターし、ビジネス・ロジックをサービス・クラスに移動します。これは上記の登録とログインのシナリオの場合、リスト 5 のようになります。
リスト 5. サンプルの AdvertiserService
class AdvertiserService {
boolean transactional = true
def advertiserExists(String name){
def exists = Advertiser.findWhere(name:name)
exists != null
}
def login(String name, String password){
Advertiser.findWhere(name:name, password:password)
}
}
|
Grails が Spring フレームワークなど実証済みの Java 技術の上に構築されていることを思い出してください。Grails のサービス・クラスは Spring Bean になります。サービスはデフォルトでシングルトンです (Spring を直接使う場合とまったく同じです)。またサービスを他の Spring Bean に注入することもでき、そして都合の良いことにコントローラーもすべて Spring Bean です。この場合にも Convention over Configuration の原則を生かし、コントローラーの中のサービスを容易に参照することができます。
リスト 6. コントローラーの中でサービスを使う
class LoginController {
def advertiserSerivce
def index = { }
def login = {
def advertiser = advertiserService.login(params.name, params,password)
if (!advertiser){
flash.message = "The password does not match the name of the advertiser"
redirect(action:index)
}
session.advertiser=advertiser
redirect(controller:"ad",action:"adsFor")
}
}
|
xyzService という規約に従うメンバー変数があるだけで、Grails は xyzService シングルトンを注入するのだということを理解します。この例では単純にするためにサービス・レイヤーに関してはあまり気にしませんが、Grails のこの機能こそ、迅速な開発、そして Convention over Configuration に従った他の多くのフレームワークから Grail を明確に区別する機能であることを理解することが重要です。ではアプリケーションのコードに戻り、広告がどのように作成され、提供されるのかを調べてみましょう。
広告を作成し、提供する
ここまでの時点で、2 つのコントローラーがあります。1 つは登録のためのコントローラーであり、もう 1 つはこの広告ネットワークにログインするためのコントローラーです。どちらのコントローラーも、さらに別のコントローラー (AdsController) にコントロールを転送します。
リスト 7. AdsController
import grails.converters.XML
class AdController {
def index = { redirect(action:list,params:params) }
// the delete, save and update actions only accept POST requests
def allowedMethods = [delete:'POST', save:'POST', update:'POST', placement:'GET']
def adsFor = {
render(view:"list", model:[adList: Ad.findAllWhere(advertiser :
session.advertiser )]);
}
def list = {
if(!params.max) params.max = 10
[ adList: Ad.list( params ) ]
}
def placement = {
def ads = Ad.findAll("from Ad as ad where ad.keywords like
'%"+params.keyword+"%' order by ad.bid desc")
render ads as XML
}
def show = {
def ad = Ad.get( params.id )
if(!ad) {
flash.message = "Ad not found with id ${params.id}"
redirect(action:list)
}
else { return [ ad : ad ] }
}
def delete = {
def ad = Ad.get( params.id )
if(ad) {
ad.delete()
flash.message = "Ad ${params.id} deleted"
redirect(action:list)
}
else {
flash.message = "Ad not found with id ${params.id}"
redirect(action:list)
}
}
def edit = {
def ad = Ad.get( params.id )
if(!ad) {
flash.message = "Ad not found with id ${params.id}"
redirect(action:list)
}
else {
return [ ad : ad ]
}
}
def update = {
def ad = Ad.get( params.id )
if(ad) {
ad.properties = params
if(!ad.hasErrors() && ad.save()) {
flash.message = "Ad ${params.id} updated"
redirect(action:show,id:ad.id)
}
else {
render(view:'edit',model:[ad:ad])
}
}
else {
flash.message = "Ad not found with id ${params.id}"
redirect(action:edit,id:params.id)
}
}
def create = {
def ad = new Ad()
ad.properties = params
return ['ad':ad]
}
def save = {
def ad = new Ad(params)
if (session.advertiser){
ad.advertiser = session.advertiser
}
if(!ad.hasErrors() && ad.save()) {
flash.message = "Ad ${ad.id} created"
redirect(action:show,id:ad.id)
}
else {
render(view:'create',model:[ad:ad])
}
}
}
|
scaffold コマンド (generate-all ad) を使ったことがある人であれば、このコードはほとんど理解できるでしょう。ただしこのコードはいくつかの点がカスタマイズされています。ここには adsFor メソッドを追加してあります (上記の登録コントローラーとログイン・コントローラーから、このメソッドに対して転送しています)。このメソッドはセッションの advertiser を使うことで、その advertiser が所有するすべての広告を取得し、それを「list」ビューに表示します。save メソッドもセッションの advertiser を使うように変更されています。そしてついに、placement メソッドが追加されました。このメソッドは会員が広告を検索するために使用するメソッドで、keyword パラメーターを取り、このキーワードが含まれるすべての広告を取得します。また、このメソッドは HQL (Hibernate Query Language) を使ったカスタムのクエリーを使います (このクエリーは XML を使ってデータをシリアライズする REST Web サービスです)。Grails ではそれを、単に render ads as XML を返すだけで容易に行えるようになっています。それほど多くのコードを追加しなくても、すべてのユース・ケースを処理できるようにアプリケーションをカスタマイズすることができました。Grails の stats コマンドを使うと、実際に作成したコードがいかに少ないか、即座にわかります。
リスト 8. adserver アプリケーションの stats
$ grails stats
Welcome to Grails 1.0.2 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: /Users/michael/lib/grails-1.0.2
Base Directory: /Users/michael/code/grails/adserver
Note: No plugin scripts found
Running script /Users/michael/lib/grails-1.0.2/scripts/Stats.groovy
Environment set to development
+----------------------+-------+-------+
| Name | Files | LOC |
+----------------------+-------+-------+
| Controllers | 4 | 179 |
| Domain Classes | 2 | 15 |
| Services | 1 | 10 |
| Integration Tests | 5 | 20 |
+----------------------+-------+-------+
| Totals | 12 | 224 |
+----------------------+-------+-------+
|
ご覧のとおり、それほど大量のコードではありません。実際、大部分のコードは、advertiser と ad に対する scaffold である generate-all を使って生成したコードです。Grails では開発を容易にするために、あまり大量のコードを作成しなくてもすむようになっています。またテストも容易に行えるようになっています。
アプリケーションをテストする
アプリケーションを実行するためには、単純に Grails の run-app コマンドを実行します。それによって組み込みのメモリー内データベースと組み込みの Jetty Web コンテナーを使用するスクリプトが呼び出されるため、スタンドアロンのサーバーやデータベースをセットアップする必要がありません。即座に http://localhost:8080/adserver に行くことができ、またコントローラーなどにアクセスできるはずです。アプリケーションのテストとデバッグが終わると、そのアプリケーションを Geronimo で使い始めることができます。
Geronimo を活用する
ここまでの時点で、すべてのユース・ケースを満足する Web アプリケーションを作成しました。Grails を利用したため、アプリケーションの作成は迅速であり、作成するコードの量も少なく済みました。もちろん、作成するコードの量が少ないというのは相対的な言い方にすぎず、何に比べて少ないかというと、典型的な Java Web アプリケーションと比べて、というのが答えです。Grails を利用することで、典型的な Java Web アプリケーションよりも迅速かつ少ないコード作成量で開発できるのは間違いありませんが、そこに何らかの代償はあるのでしょうか。幸いなことに Grails アプリケーションは Java の Web アプリケーションです。Grails ではアプリケーションを標準の Java Web アプリケーション (WAR) としてパッケージ化することができ、また (Apache Geronimo を含む) 任意の Java Web コンテナーにデプロイすることができます。では、Grails の adserver アプリケーションをどのように Geronimo にデプロイするのかを調べてみましょう。
Grails の WAR をデプロイする
この Grails アプリケーションを Geronimo にデプロイするための最初のステップは、WAR を作成することです。Grails のディレクトリー構造を見ると、そのための Ant スクリプトを作成することはそれほど難しくないようです。しかし幸いなことに Grails ではもっと容易に作成できるように、単純な Grails コマンド、war が用意されています。このスクリプトは grails-app ツリーのコードをコンパイルし、それを Grails のベース・ディレクトリー ($GRAILS_HOME) のコードと組み合わせます。その結果が /web-app ディレクトリーに追加されます。ここでは Geronimo を使っているので、Geronimo のデプロイメント・プランを追加する必要があります。そこで単純に /web-app/WEB-INF の中に geronimo-web.xml を作成します。
リスト 9. Geronimo のデプロイメント・プラン
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://geronimo.apache.org/xml/ns/j2ee/web-1.1">
<environment xmlns="http://geronimo.apache.org/xml/ns/deployment-1.1">
<moduleId>
<groupId>grailsApps</groupId>
<artifactId>AdServer</artifactId>
<version>0.1</version>
<type>war</type>
</moduleId>
<hidden-classes>
<filter>org.springframework</filter>
<filter>org.apache.cxf</filter>
<filter>org.apache.commons</filter>
</hidden-classes>
</environment>
<context-root>/adserver</context-root>
</web-app>
|
ここで、1 つ非常に重要なことに注目する必要があり、それが hidden-classes セクションです。このセクションで指定されているパッケージはデフォルトで Geronimo に含まれているパッケージですが、Grails にも含まれています。このセクションはこの Grails アプリケーションをロードするクラス・ローダーに対して、親のクラス・ローダー (つまりコンテナーのクラス・ローダー) から利用できるこれらのパッケージのクラスをすべて無視するように指示しています。これによって、Grails に含まれる方のパッケージのクラスが必ずロードされ、やっかいなクラス・ローダーの競合が起きないことも保証されます。
これで、Grails の war コマンドを実行する準備ができました。リスト 10 は、このコマンドが実行される様子と、このコマンドの出力を示しています。
リスト 10. war コマンドを使う
$ grails war
Welcome to Grails 1.0.2 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: /Users/michael/lib/grails-1.0.2
Base Directory: /Users/michael/code/grails/adserver
Note: No plugin scripts found
Running script /Users/michael/lib/grails-1.0.2/scripts/War.groovy
Environment set to production
[delete] Deleting: /Users/michael/.grails/1.0.2/projects/
adserver/resources/web.xml
[delete] Deleting directory /Users/michael/.grails/1.0.2/projects/adserver/classes
[delete] Deleting directory /Users/michael/.grails/1.0.2/projects/adserver/resources
[mkdir] Created dir: /Users/michael/.grails/1.0.2/projects/adserver/classes
[groovyc] Compiling 13 source files to /Users/michael/.grails/1.0.2/
projects/adserver/classes
[mkdir] Created dir: /Users/michael/.grails/1.0.2/projects/adserver/
resources/grails-app/i18n
[native2ascii] Converting 10 files from /Users/michael/code/grails/adserver/
grails-app/i18n to /Users/michael/.grails/1.0.2/projects/adserver/resources/
grails-app/i18n
[copy] Copying 1 file to /Users/michael/.grails/1.0.2/projects/adserver/classes
[copy] Copying 1 file to /Users/michael/.grails/1.0.2/projects/adserver/resources
[mkdir] Created dir: /Users/michael/code/grails/adserver/staging
[copy] Copying 93 files to /Users/michael/code/grails/adserver/staging
[copy] Copied 19 empty directories to 1 empty directory under /Users/michael/
code/grails/adserver/staging
[copy] Copying 23 files to /Users/michael/code/grails/adserver/staging/
WEB-INF/grails-app
[copy] Copying 55 files to /Users/michael/code/grails/adserver/staging/
WEB-INF/classes
[mkdir] Created dir: /Users/michael/code/grails/adserver/staging/
WEB-INF/spring
[copy] Copying 1 file to /Users/michael/code/grails/adserver/staging/
WEB-INF/classes
[mkdir] Created dir: /Users/michael/code/grails/adserver/staging/
WEB-INF/templates/scaffolding
[copy] Copying 6 files to /Users/michael/code/grails/adserver/staging/
WEB-INF/templates/scaffolding
[copy] Copying 50 files to /Users/michael/code/grails/adserver/staging/
WEB-INF/lib
[copy] Copying 1 file to /Users/michael/code/grails/adserver/staging/
WEB-INF
[delete] Deleting: /Users/michael/.grails/1.0.2/projects/adserver/resources/web.xml
[copy] Warning: /Users/michael/code/grails/adserver/plugins not found.
[propertyfile] Updating property file: /Users/michael/code/grails/adserver/staging/
WEB-INF/classes/application.properties
[mkdir] Created dir: /Users/michael/code/grails/adserver/staging/WEB-INF/plugins
[copy] Warning: /Users/michael/code/grails/adserver/plugins not found.
[jar] Building jar: /Users/michael/code/grails/adserver/adserver-0.1.war
[delete] Deleting directory /Users/michael/code/grails/adserver/staging
Done creating WAR /Users/michael/code/grails/adserver/adserver-0.1.war
|
この WAR をデプロイするためには、この WAR を Geronimo のデプロイメント・ディレクトリー ($GERONIMO_HOME/deploy、ここで $GERONIMO_HOME は Geronimo がインストールされている場所です) に置くか、あるいは Geronimo のコンソールを使います。
図 2. Geronimo のコンソールを使って Grails の WAR をデプロイする
リスト 9 に示した Geronimo のデプロイメント・プランではアプリケーションのコンテキスト・パスを /adserver に設定したため、http://localhost:8080/adserver を指定すると、デプロイされたアプリケーションが表示されます。これで Grails アプリケーションが Geronimo 上で実行されるようになります。では、Geronimo をどのように使えばこのアプリケーションを機能強化できるかを調べてみましょう。
データベース・プールを作成する
データベース接続プールを使うことで大きくパフォーマンスを改善できることはよく知られています。つまり、Web アプリケーションに対するリクエストごとにデータベース接続を作成する、というオーバーヘッドを大幅に削減できるのです。そのため、Java Web アプリケーションでデータベース接続プールを設定することは非常に一般的です。Geronimo のようなアプリケーション・サーバーでは、そうしたプールを一層容易に作成することができ、作成されたプールは Geronimo にデプロイされた任意のアプリケーションで再利用することができます。プールの作成は Geronimo のコンソールから容易に行うことができます (図 3)。
図 3. Geronimo でデータベース・プールを作成する
これでデータベース・プールを作成できたので、あとは Grails アプリケーションからこのプールに接続すればよいだけです。そのためにはいくつかのステップが必要です。
Grails からデータベース・プールにアクセスする
データベース・プールは Java の DataSource オブジェクトとして表現され、JNDI にバインドされているため、任意のアプリケーションがデータベース・プールを使用することができます。このデータベース・プールを Web アプリケーションで利用するためには、このプールが web.xml ファイルの中で参照されている必要があります。しかしちょっと待ってください。どんな web.xml なのでしょう。実は Grails は $GRAILS_HOME/conf/webdefault.xml をベースに web.xml を作成してくれるので、このファイルを編集することもできますし、あるいは WAR を生成して解凍し、それによって生成される web.xml を編集することもできます。いずれにせよ、リスト 11 に示すセクションをこのファイルに追加する必要があります。
リスト 11. web.xml の中で DataSource を参照する
<resource-ref>
<res-ref-name>jdbc/MyDataSource</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.xml ファイルの末尾の直前に追加されます。次に、Geronimo のデプロイメント・プランへの参照を追加する必要があります。
リスト 12. Geronimo の新しいデプロイメント・プラン
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://geronimo.apache.org/xml/ns/j2ee/web-1.1">
<environment xmlns="http://geronimo.apache.org/xml/ns/deployment-1.1">
<moduleId>
<groupId>grailsApps</groupId>
<artifactId>AdServer</artifactId>
<version>0.1</version>
<type>war</type>
</moduleId>
<hidden-classes>
<filter>org.springframework</filter>
<filter>org.apache.cxf</filter>
<filter>org.apache.commons</filter>
</hidden-classes>
<dependencies>
<dependency>
<groupId>console.dbpool</groupId>
<artifactId>adserver</artifactId>
</dependency>
</dependencies>
</environment>
<context-root>/adserver</context-root>
<resource-ref>
<ref-name>jdbc/MyDataSource</ref-name>
<resource-link>adserver</resource-link>
</resource-ref>
</web-app>
|
adserver というデータベース・プールを呼び出していること、その呼び出しをしているのが resource-ref の中にある resource-link と、その依存関係であることに注目してください。デプロイメント・プランの中の ref-name はリスト 11 に示した web.xml のスニペットの中の res-ref-name と一致している必要があります。これで Geronimo と Web アプリケーションの間が接続されます。
これで、アプリケーションが接続プールを利用できるようになりました。ではどのようにして接続プールにアクセスするのでしょう。Grails のおかげで、この部分が容易になるのです。必要なことは /grails-app/conf/DataSource.groovy を編集することだけです。
リスト 13. DataSource.groovy
dataSource {
jndiName = "java:comp/env/jdbc/MyDataSource"
}
hibernate {
cache.use_second_level_cache=true
cache.use_query_cache=true
cache.provider_class='org.hibernate.cache.EhCacheProvider'
}
// environment specific settings
environments {
development {
dataSource {
dbCreate = "update"
}
}
test {
dataSource {
dbCreate = "create-drop"
}
}
production {
dataSource {
dbCreate = "create"
}
}
}
|
通常は最初の dataSource ブロックで JDBC のプロパティー (ドライバー・クラスやユーザー名、パスワードなど) を定義します。しかし今や JNDI の名前を提供するだけでよくなりました。この名前は、web.xml ファイルの中で res-ref-name に指定したものを「java:comp/env/」に加えたものでなければなりません。これらの設定はすべて、(通常の場合と同様に) 環境に合わせた設定にすることができます。
まとめ
この記事では、Grails によって Web アプリケーションの作成がどれほど迅速になるかを説明しました。Grails では Convention over Configuration の原則が使われているため、よく使われるさまざまな技術を苦労せずに組み合わせることができます。規約に従うことで、Grails が作業を楽にしてくれるのです。ビジネス・ロジックのためのコードは相変わらず作成する必要がありますが、そうしたコードでさえ、Groovy プログラミング言語の豊かな表現力のおかげで最小限で済みます。この Grails による素晴らしい効果に加え、Grails と Geronimo を組み合わせることによって、さらに素晴らしい結果がもたらされます。Grails アプリケーションは他の任意の Java Web アプリケーションとまったく同じように実行され、Java Web アプリケーションと似た方法で Geronimo のリソースにアクセスできるため、Geronimo の持つ能力のすべてを活用することができます。この記事を出発点として、メッセージングなど Geronimo が持つ他の機能も利用して Grails アプリケーションを一層高度なものにすることができます。あるいは Geronimo のクラスターにデプロイすることで Grails アプリケーションを一層スケーラブルにすることもできます。
ダウンロード | 内容 | ファイル名 | サイズ | ダウンロード形式 |
|---|
| Sample code | os-ag-grails.adserver.example.zip | 829KB | HTTP |
|---|
参考文献 学ぶために
製品や技術を入手するために
著者について  | 
|  | Michael Galpin は、1998年以来、プロとして Java ソフトウェアを開発してきています。彼は現在 eBay に勤務しています。彼は California Institute of Technology で数学の学位を取得しています。 |
記事の評価
|