
業務アプリもJ2EE一辺倒からWeb 2.0的な軽量技術が現実解に
|
業務で使用されるWebアプリケーションの開発では、これまでJ2EEが独壇場とも言える地位を占めてきた。ところが最近、“Web 2.0的”と表現される軽快で生産性の高い開発手法が、現実的な実装技術として検討されつつある。本パートでは、世界中の開発者に大きなインパクトを与えたAjax やRuby on Railsをはじめ、EJB 3.0/JPA、SOAP/RESTなど、今後Webアプリケーションを変えていくであろう新技術の概要を見ていく。
Web 2.0の技術面での価値とは
業務システムとしてもすでに一般化した感のあるWebアプリケーションだが、最近新たな潮流が起こりつつある。その大きなものの1つが「Web 2.0」である。
Web 2.0は非常に抽象的な概念で、理解しづらい面があるが、本パートでは「ユーザー の参加を積極的に促す仕組みを備える双方向的なアプリケーション」と定義する。Amazonのカスタマーレビュー、Flickrのタギング(注1)、はてなのソーシャルブックマーク(注2)などが、Web 2.0的なサービスの代表例として挙げられるだろう。このようなWeb 2.0アプリケーションは、従来のWebアプリケーションとは異なり、以下のような特徴を持っている。
- 頻繁にサイトの機能を追加
非常に短い間隔(数時間~数週間程度)でシステムをアップデートすることが多い。ユーザーに積極的な参加を促す目的もある。
- Webサイトが持っている機能をWebサービス化して公開
Google MapsやAmazon Web Serviceなどが代表例。こうしたWebサービスを積極的に 利用することで、アプリケーションの開発量を減らし、本質的な部分(競争力の源泉になるような部分)に注力できる。
- 従来のWebアプリケーションでは考えられなかったような高い操作性を実現
Ajaxなどの技術で実現され、①と同様にユーザーの参加を促す目的もある。
こうした状況であるため、現在ではWebアプリケーションの構築に使用する要素技術を、多くの中から選択できるようになっている。少し前まで、商用/業務用のWebアプリケーションと言えばJ2EE環境(注3)で構築するものと決まっていたが、Web 2.0アプリケーションでは非常に短いサイクルでシステムをアップデートする必要性から、RubyやPerl、PHPなどのスクリプト言語が採用されるケースが増えている。また、Windowsプラットフォームの成熟とともに、.NETも選択肢として存在を大きくしている。
また、これまでWebブラウザ間の互換性に問題があり、むしろ使用が敬遠されてきたJavaScriptが、Ajaxが実現した高機能なユーザーインターフェイス(多くの人がGoogle Mapsに衝撃を覚えたのではないだろうか)の登場により、今やWebアプリケーションのクライアント技術として重要な位置を占めている。
このように、現在のWebアプリケーションは、 企業システムとしての利用に耐える高信頼性を求められることがある一方、数時間ごとのシステムアップデートに対応できる柔軟性を求められる場合もあるのだ。また、非常にリッチなユーザーインターフェイスの実現を求められる場合もある。当然、これらの多岐にわたる要件を単一の技術でカバーすることには無理があるため、これからのWebアプリケーション構築では、適切な技術を選択するための知識が必要不可欠と言えるだろう。
そこで本パートでは、現在注目されているWebアプリケーションの構築に関係の深い技術のうち、必ず理解しておきたいものを紹介する。本文で説明できなかった技術のいくつかはコラムとして取り上げているので、そちらも併せてご覧いただきたい。
軽量EJBを追加したJava EE 5
Java EE 5(EE=Enterprise Edition)は、今年の5月にSDKが正式リリースされたエンタープライズ向けJava技術の最新仕様である。Java EE 5はServlet 2.5などの個別仕様をまとめたものだが、ここでは特に注目度が高いと思われる「EJB(Enterprise Java Beans)3.0」と「JPA(Java Persistence API)」を取り上げる。
なお、Java EE 5に含まれる仕様の1つ「JSF(JavaServer Faces)」については後ほど紹介したい。
複雑さを排除したEJB 3.0
EJBは、企業向けのアプリケーションを構築するためのテクノロジーとして登場した。ビジネスロジックをコンポーネント化し、再利用することで企業向けアプリケーションの開発生産性を高めるというのが主なねらいである。また、分散トランザクションや分散オブジェクトといった、大規模な企業向けアプリケーションで使用される技術をアプリケーション開発者から隠蔽し、ビジネスロジックの開発に集中してもらおうという目的もあった。
このようなEJB自体のコンセプトは理にかなっていたが、現時点でEJBが積極的に使われているかというと、そうとは言えない。これにはいくつか理由がある。
● EJBコンポーネントの開発では非常に多くの規約を守る必要があり、開発そのものが難しい
● EJBコンポーネントの動作確認にはEJBコンテナ(注4)が必要となるため、単体テストが実施しづらい
● そもそも、分散トランザクションや分散オブジェクトを使わなければならないアプリケーションは非常に限られている。これらの技術を使う必要がないシステムの開発ではEJBが定める規約は重すぎて、かえって生産性を下げてしまう
こうした理由から、EJBを利用するシステム開発というのは数が少ないのが現状だ。大部分のシステム開発は、EJBを使わずにJSPやServlet、そのほかさまざまな永続化フレームワーク(注5)という構成で開発されている(注6)。
これらの反省点を踏まえ、EJB 3.0では複雑さを排し、より簡単にEJBコンポーネントを開発できることを目指している。EJBにおいては、これまでで最もドラスティックな仕様変更と言えるだろう。
それでは、どの程度簡単になっているのか、少し具体的に見てみよう。図1は、EJB 3.0以前の典型的なEJBの構成を表わしたものである。
Session BeanとEntity Beanは、あらかじめ定義されているインターフェイスを実装しなければならない。ただし、EJBコンポーネントをインスタンス化するためのHomeインターフェイスや、ビジネスロジックを呼び出すためのComponentインターフェイスとEJBコンポーネント(FooBean、BarBean)との間には直接の実装関係はない。インターフェイスとEJBコンポーネントの関係は、デプロイメントディスクリプタと呼ばれる専用のXMLファイルで定義する。
このように、EJBコンポーネントの全容を把握するためには散在する情報を読み解かねばならないし、Home/RemoteインターフェイスとEJBコンポーネントとの関係のようにEJBの構造は直感的に理解しづらい。こうしたことがEJBが敬遠される原因となってきたのである。
これに対して、EJB 3.0の構成は図2のように非常にシンプルだ。
これまで、インスタンス生成とビジネスロジックの呼び出しという2種類のインターフェイスが必要だった部分が、Businessインターフェイスという1つのインターフェイスにまとめられている。また、各Beanは特定のインターフェイスを実装する必要はなくなり、代わりにJ2SE 5から導入された「アノテーション」という言語機能を使ってEJBであることを宣言している。
つまり、EJB 3.0のEJBコンポーネントは特別なクラスではなく、「POJO(Plain Old JavaObject)(注7)」だということを意味する。POJOなら、EJBコンテナなしで動作させることができるので、単体テストも簡単に実施できる。この点は、EJBコンポーネントの生産性や信頼性の向上に大きく寄与するだろう。

図1 EJB 2.xまでの構成

図2 EJB 3.0の構成
O/Rマッピング機能を提供するJPA
JPAは、これまでCMP(Container-Managed Persistence)Entity Beanが担っていたJavaオブジェクトをRDBに永続化する機能(O/Rマッピング)をAPIとして独立させたものである。したがって、Java EEの一部ではあるものの、EJBとはまったく独立したAPIである(注8)。
特筆すべきは、このAPIがJ2SEからも利用可能な点だろう。スタンドアロンアプリケーションであっても、Java標準のO/RマッピングAPIを使用できるのである。
ここからは、最も人気のあるJPA実装の1つ「Hibernate」を使った簡単なサンプルコードを見ながら、JPAの理解を深めていこう。まずは、永続化対象のコードを見てみよう。ここでは、少しのプロパティを持つ “User”というクラスを用意した。
LIST1をご覧いただきたい。Userは単なるJavaクラスである。ただし、アノテーションによってこれがEntity Beanであることと、テーブル上の主キーに関する情報が定義されている。永続化先のテーブルUSERの定義はLIST2のとおりとする。
次に、JPAを使用するクラスを見てみよう(LIST3)。このクラスは、mainメソッドを持つごく普通のクラスである。最初に、JPAで定義されているEntityManagerクラスを使い、Entity Beanに格納するデータをDBから読み出し、Userのインスタンスを取得している。
JPAでオブジェクトを永続化する場合、必ずEntity Beanが必要となる。JavaオブジェクトとDB間のマッピングに関する情報は、EntityBeanにしか書けないからだ。また、LIST3には、UserクラスとDBテーブルをマッピングするためのアノテーションがない。JPAにはマッピングのためのアノテーション@Tableが用意されているが、この例のように省略もできる。その場合は、クラス名と同じ名前のテーブルにマッピングされる。
最後にもう1つ。これはJPAの規約であるが、LIST4に示すpersistence.xmlというファイルを定義する。persistence.xmlはMETAINFディレクトリの下に配置し、CLASSPATHを通しておく必要がある。
サンプルの解説は以上だが、以前のEntityBeanに比べて記述量が大幅に減っていることや、EJBコンテナがなくてもJPAを使って永続化処理を書けることがお分かりいただけたと思う。アプリケーションサーバーが存在しなくてもEntity Beanを永続化できるので、Entity BeanをEJBと呼ぶのはもはや適切でないかもしれない。
また、Java EE 5には魅力的な機能がほかにもある。最近流行のDIコンテナなどは待望の機能と言えるだろう。
LIST1 永続化対象のUserクラス
import javax.persistence.*; import java.io.*;
// アノテーション。
// このクラスがEntity Beanであることを示している@Entitypublic class User { private Integer id; private String name; private int age; public User() { }
// アノテーション。
// get/setIdメソッドでアクセス可能なプロパティ“id”がテーブル上の主キーになることを
// 意味する。また、GenerationType.AUTOによって、“id”がJPAによって自動生成されることも
// 意味する@Idpublic Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
@GeneratedValue(strategy = GenerationType.AUTO)
LIST2 永続化先のUSERテーブル
create table user( id integer, name varchar(30), age integer, primary key(id));
LIST3 JPAを使用するクラス
import javax.persistence.*;
public class JPATest {
public static void main(String[] args) {
// JPAのEntityManagerのインスタンスを、EntityManagerFactoryクラスを使って取得しているEntityManagerFactory aFactory =
Persistence.createEntityManagerFactory("jpatest");
EntityManager aManager = aFactory.createEntityManager();
// EntityManagerのメソッドfindを使って、データベース上に永続化されているUserを
// インスタンス化する。第1引数にはインスタンス化するクラスのクラスオブジェクトを、
// 第2引数には、インスタンスを識別するためのデータ(この場合は主キーの値)を指定している
User aUser = aManager.find(User.class, new Integer(1)); System.out.println("name = " + aUser.getName());
aManager.close();
aFactory.close();
}
}
LIST4 persistence.xml
<persistence>
<!-- この部分のnameプロパティで指定している名称は、先ほどのEntityManagerFactoryに
渡している引数と一致している必要がある。また、transaction-typeプロパティの値は
トランザクション制御にJTAを利用しないことを意味している --><persistence-unit name="jpatest" transaction-type="RESOURCE_LOCAL">
<!-- この部分はおなじみのJDBCの設定である。各自の環境に合わせて変更してほしい --><properties></properties> </persistence-unit> </persistence>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
<property name="hibernate.connection.username" value="userid"/>
<property name="hibernate.connection.password" value="password"/>
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/jpadb"/>
<property name="hibernate.max_fetch_depth" value="3"/>
超効率開発が可能な Ruby on Rails
「Ruby on Rails」(以下、Rails)とは、スクリプト言語Rubyで開発されたWebアプリケーション開発用フレームワークである。2004年に公開されて以降、作者のデビッド・ハイネマイヤ・ハンソン氏が中心となって開発が続けられている。いま最も注目度が高い技術の1つであり、現場で使われるケースも増えてきている。
Railsでは、図3のように極めてシンプルな MVC(Model/View/Controller)アーキテクチャを採用している。「ルータ」はRailsが提供しているコンポーネントで、URLを解析し、適切なコントローラを探し出して処理を委譲する役割を持つ。コントローラとビューは文字どおりの意味なのであまり説明の必要はないだろう。モデルについてだけ簡単に補足しておく。
Railsのモデルクラスは「アクティブレコード」と呼ばれている。これは、マーチン・ファウラー氏の著書「エンタープライズアプリケーションアーキテクチャパターン」で紹介されているアクティブレコードというパターンを実装したもので、モデルクラスがDBの永続化処理とビジネスロジックの処理を担当する。したがって、コントローラの役割は、モデルクラスのメソッドを呼び出すことによってビジネスロジックを呼び出すことになる。図4のように、モデルクラスはDBテーブルと1対1に対応して作成される。
また、Railsは次のような特徴を持っている。
● Convention over Configuration
● DRY(Don't Repeat Yourself)
● ジェネレータ
● フルスタック
それぞれについて簡単に説明していこう。
Convention over Configuration
「設定よりも規約」と訳されるこの特徴は、Railsを理解する上で非常に重要な概念だ。Railsには、さまざまなデフォルトの振る舞いが用意されている。このデフォルトの振る舞いがうまく機能するために、さまざまな規約が定められている。プログラマは、この規約に沿ってコードを書くことが推奨されており、規約(「DBテーブル名は複数形で書く」「モデルクラス名はテーブル名の単数形にする」など)に沿ってさえいれば、コードの記述量を大幅に削減できるのである。
このような振る舞いは、例えばJ2EEのようなプラットフォームであれば、XMLファイルでプログラマが設定するような類のものである。当然、XMLファイルで任意に設定できたほうが柔軟性は増すが、プログラマの記述量は増える。Railsでは、不要な柔軟性を排除するという割り切りのもとで(注9)、コードの記述量を削減することを選択しているのである。
DRY
DRYはDon't Repeat Yourselfの略で、「同じことを繰り返し記述するのはやめよう」という考え方である。もともとは「達人プログラマ」という書籍で紹介されている考え方である。Railsはこの思想が貫かれており、プログラマが同じような記述を繰り返し書かなくて済むようになっている。
ジェネレータ
Railsには非常に強力なコードジェネレータが付属している。MVCの各雛形クラスはもちろん、テストコードやアプリケーションを構成するさまざまなファイルを自動生成してくれる。ジェネレータで雛形ファイルを作り、それを修正していくのが、Railsの開発スタイルである。
Railsのジェネレータの強力さを端的に表わしているのが、「scaffold(足場という意味)」だろう。scaffoldは、コマンド1つでDBテーブルのCRUD操作を実現するモデル/ビュー/コントローラを生成してくれる。画面デザインにこだわらなければ、マスターテーブルをメンテナンスするアプリケーションくらいなら、コマンド1つで作れてしまうのだ。
フルスタック
Railsには、Webアプリケーションの構築に必要な以下の要素がすべて含まれている。Railsさえ入手すれば、Webアプリケーションの構築に困ることはないだろう。
● 主に開発時に利用されるWebサーバー(WEBRick(注10))
● 開発用/テスト用/本番用のそれぞれ独立した環境
● 単体テストフレームワーク
● Webサービス/Ajax/電子メールなどのサポート
このようなさまざまなメリットを持つRailsではあるが、次のような弱点もある。
- RailsのというよりRubyの弱点であるが、変数に型が存在しないため、実行しないとデータ型の不一致が判明しない
- 2フェーズコミットが現段階ではサポートさ れていない
これらの点を踏まえると、Railsは高信頼性システムや分散DBシステムには向いていないと言える。逆に、こうしたシステム以外にはRailsを使っても問題ないだろう。RailsとRubyが持つ高い生産性やスクリプト言語特有のターンアラウンドタイム(実装と改善の繰り返しにかかる時間)の短さを考えると、次のようなプロトタイピングを伴うシステム開発には、むしろうってつけと言えるのではないだろうか。
● Web 2.0に代表されるような、短い間隔で機能を頻繁に追加するようなシステム
● まったく新規のビジネスを実現しなければならないようなシステム

図3 Ruby on Railsのアーキテクチャ

図4 モデルクラスとDBテーブルは1対1に対応して作成される
コラム : 業務アプリ環境としての.NETの優位点
.NET Framework(以下、.NET)は、マイクロソフトが開発したアプリケーション開発/実行環境だ。リッチクライアントでは本命視する声もある。ここでは、筆者の考える.NETの優位点をいくつか紹介しよう。
無償版Visual Studioの提供
Visual Studioは、特にその使い勝手の良さが高い評価を得ている開発環境だ。しかし、比較的高価なため、個人が.NETの習得用にこの環境を使うのは難しかった。しかし、Visual Studio 2005から無償で利用可能なExpress版が登場した。もちろん機能制限はあるが、.NETの評価や学習用には十分な機能を備えている。これまで、.NETを習得しようと思うと、.NET SDK(Javaで言うところのJDK)を使うか、Visual Studioを買ってくるかしかなく、若干敷居が高かった(注)。Express 版のおかげで、.NET開発を始める技術者も増えるだろう。
ADO.NETは優れたDBアクセス技術
DBアクセス技術であるADO.NETも、.NETの優位点の1つだろう。ADO.NETはマイクロソフト製のO/Rマッピングフレームワークと言える。基本的なアーキテクチャは、マーチン・ファウラー氏が提唱したデザインパターン「テーブルデータゲートウェイ」と同様で、Railsのアクティブレコードとは異なり、1つのDataSetオブジェクトがテーブル全体を管理する。受注/受注明細テーブルのような親子関係を持つテーブルを、1 つのDataSetで管理することも可能だ。DataSetはVisual Studioのウィザード機能で 簡単に作成できるので、例えば画面に表示するデータ構造に準拠したDataSetを作ることで、画面とDB間の入出力のコードを省くことも可能だ。あくまで概念的ではあるが、図AようなDB、DataSet、画面間の接続を、Visual Studioを使えばグラフィカルに行なうことができる。
自動アップデート機能ClickOnce
ClickOnceとは、.NET Framework 2.0で追加されたアプリケーションの配布/更新技術だ。ClickOnceを利用したインストーラでアプリケーションをインストールすると、そのアプリケーションの起動時に、新バージョンの有無が自動的にチェックされ、新しいバージョンがリリースされていれば、インストールするかどうかをユーザーに問い合わせる。この仕組みにより、アプリケーションの配布やバージョンアップの手間を 劇的に減らせるのである。

図A DB、DataSet、画面間を接続
(注):C#アプリケーションは、Eclipseで提供されている環境で開発することもできた。
(注1)Flickrは、参加者が写真をアップし、共有するWebサイト(http://www.flickr.com/)。タギングとは参加者が写真に「言葉(タグ)」付けることを言い、検索キーとして使える。
(注2)はてなは、ブログやRSSリーダーといったサービスを提供するコンテンツプロバイダ(http://www.hatena.ne.jp/)。ソーシャルブックマークとは、参加者が気に入ったWebサイトを登録し共有するサービス。
(注3)EJBを使わず、JSP/Servletなどの組み合わせで済ませるようなシステムも含む。
(注4)EJBの実行環境。アプリケーションサーバーという形態で製品化されている。
(注5)業務アプリケーションで扱うデータをDB に格納するためのフレームワーク。
(注6)最近ではStruts+Spring もしくはSeaser2+Hibernateという組み合わせも多いと思われる。
(注7)マーチン・ファウラー氏による造語で、名前のとおり「昔からある普通のJavaオブジェクト」といったような意味である。EJBコンポーネントのような、ある決まったインターフェイス実装や継承を求められたり、特別な環境でしか実行できないようなJavaオブジェクトとの対比で使われる。
(注8)Entity BeanはJavaオブジェクトとRDBとのマッピングを定義するだけで、永続化処理は行なわないことになる。
(注9)規約自体を変更することも可能ではある。
(注10)このWebサーバーはすべてRubyで記述されている。