Strutsを使い続けることの問題点&現在有力なJava EE、Spring、Play Frameworkの基礎知識とアーキテクチャ:3つのフレームワークで学ぶエンタープライズJava開発入門(1)
新規のエンタープライズJava開発において現在有力視される3つのフレームの違いについて解説する連載。初回は、Strutsを使い続けることの問題点と3つの概要、アーキテクチャ、使い分けについて。
新規のエンタープライズJava開発において現在有力視される3つのフレームワーク、Java EE、Spring Framework、Play Framework。本連載では、3つの違いについて、アーキテクチャ、UI開発/画面の作り方、画面遷移、セッション管理、トランザクション、DBアクセス、開発生産性(ツール/デプロイ/CI/テスト)、外部システムとの連携などの観点から見ていきます。
Struts 1終了から2年が経過。新規のエンタープライズJava開発、どうしてますか?
エンタープライズJava開発に従事している方であれば、一度はStruts 1を扱ったことがあるでしょう。Struts 1はJavaのWebアプリケーションフレームワークとして2001年ごろに誕生しました。
MVCモデルに基づいたアーキテクチャと高い生産性から、数年後にはデファクトスタンダードとなるほどの人気を獲得。当時、多くの企業がこぞってStruts 1を使った企業システムを構築しました。筆者自身が業界に入ったのは2004年のこと。最初に参加したプロジェクトがStruts 1を使った企業システムの構築だったことをよく覚えています。
当時に作られたシステムの多くは、今でも現役で稼働しています。最近でもStruts 1ベースの企業システムを改修する話はよく聞きます。しかし、2013年にサポート終了を迎えたため、今後Struts 1を使い続けることは大きなリスクになりました(参考)。つまり、新たな機能の追加やバグ/脆弱(ぜいじゃく)性への対処が公式には行われなくなったのです。
すでに、2014年にはサーバーの不正操作が可能となる重大な脆弱性が見つかっています(参考「国内セキュリティ企業が相次いで注意喚起:Struts 2の脆弱性は最新版でも未修正、Struts 1にも同様の脆弱性が存在 - @IT」)。この脆弱性については、すでにサードパーティからセキュリティパッチが提供されていますが、いつ新たな脆弱性が発見されるとも限りません。Struts 1を使い続けることはリスクだと言わざるを得ないでしょう。
脆弱性を脇におくとしても、Struts 1は設計思想が古くなっており、開発効率という面でも難があります。例えば、以下のような欠点です。
- 長大な設定ファイルが必要で、メンテナンスコストが掛かる
- HTML5やAjaxなど最近のWeb技術に追従できていない
- Actionなど継承が強制されるクラスが、サーブレット関連のAPIに直接依存していて、単体テストの実施が困難
このような欠点は後発のフレームワークでは解消されています。あえて新規開発でStruts 1を使う理由は、もはや見当たらないでしょう。
Struts 1後の3つの有力なフレームワーク
では今後は、どのフレームワークを使えばよいのでしょうか。Struts 1が流行していた頃と異なり、今は数多くのJavaフレームワークがあります。これぞ定番というものはありませんし、何が流行しているかも分かりづらい状況です。そこで、本連載では、ポストStruts時代の本命フレームワークを考えます。
具体的には、現在、有力と思われる以下の3つのフレームワークの特徴を比較しながら、開発するシステムの規模や機能に応じた使い分けの基準を提示します。
これらを選んだ理由は次の通りです。Java EEは、Javaの標準仕様であることに加えて、豊富な機能を備えた優れた仕様であるため。Spring Frameworkは、Javaのオープンソースソフトウエア(以下、OSS)の中で最も普及したプロダクト群であるため。Play Frameworkは、軽量でありながら、ユニークな機能を備えており、ここ数年多くの技術者の注目を集めているためです。
なお、Struts 1からの移行先として、ApacheではStruts 2を勧めています。しかし、以下の点から他のフレームワークに比べてStruts 2を採用するメリットが少ないと判断しました。
- Struts 1とStruts 2の間にソースコードの互換性はないこと
- Struts 2にも重大な脆弱性が何度か発見されていること
以下、各フレームワークの特徴とアーキテクチャを見ていきましょう。
なお、アーキテクチャはMVCモデルに基づいた典型的なWebシステム、すなわちWebクライアントから情報を入力し、データベースと連携する場合の構成要素を記述しています。企業システムでは、その他にセキュリティや他システムとの連携、バッチ処理などの要素を検討する必要がありますが、ここでは「代表的な機能を中心に紹介する」ため、あえて記載していません(これらの機能は多少の差異はありますが、どのフレームワークでもサポートされています。そのため、どれを選んでも困るということはありません)。
Java EE
Java EEとは
Java EEはJavaによるエンタープライズシステムを構築するための標準仕様を定めたものです。標準仕様とは、さまざまな技術の取り扱い方を定めたAPIやフレームワーク/ライブラリの集合です。また、これらの標準仕様はコミュニティ主導で決められ、OSSとして公開されています。そのため、厳密にはフレームワークよりも広い範囲を扱うものですが、この記事ではあえてフレームワークに含めます。
なぜJava EEか。標準であることは言うまでもありませんが、機能や使いやすさでも優れているからです。近年のJava EEはSpringなど、成功を収めたオープンソースプロジェクトの良い所を取り込み、機能面や生産性が向上しています。過去の「J2EE」と呼ばれていたころは設定が複雑で、パフォーマンス的にもさまざまな課題がありましたが、現在は単純な設定で効率よく動作するように大きく改善しています。
Java EEのアップデート頻度は1〜2年に一度。他のフレームワークと比較すると、更新頻度は遅めです。そのため、最新技術への追従は遅れますが、安定感を重視するなら良い選択肢となります。
Java EEのアーキテクチャ
Java EE 7では以下の4つのカテゴリに標準仕様を分類しています。Webシステム以外のさまざまな用途にも適用できる点が特徴です(本連載では、2015年5月時点で最新である、Java EE 7を対象とします)。
- Webアプリケーション - HTMLを使用したWebアプリケーション構築に使用する。サーブレット、JSP、JSF、WebSocket API、JSON APIなど
- エンタープライズアプリケーション - 分散処理、ビジネスロジック実装、バッチ、データベース連携などを取り扱う。EJB、JMS、CDI、Bean Validation、JPA、Batch、Concurrency Utilitiesなど
- Webサービス - SOAPやRESTなどデータ送受信用のWebサービス構築に使用する。JAX-WS、JAX-RSなど
- 管理・セキュリティ - デプロイやセキュリティに関する内容を取り扱う。JACCなど
このうち、一般的なWebシステムを作る際には以下の仕様を使います。
- JSF(Java Server Faces) - コンポーネント指向のMVCのWebフレームワーク
- JAX-RS(Java API for RESTful Web Services) - RESTスタイルのWebフレームワーク
- CDI(Contexts and Dependency Injection) - Java EE標準のDI(依存性の注入)コンテナー
- JPA(Java Persistence API) - データベースとの永続化、O-Rマッピングを行うフレームワーク
これらを組み合わせたアーキテクチャは以下のようになります。
View層とController層は、JSFかJAX-RSを使用します。
JSFの場合、Faceletsという仕組みを通して生成したHTMLをViewとして使用します。Viewでの入力内容は、Controller層の「バッキングBean」というオブジェクトに渡ります。バッキングBeanは、Model層のサービスを呼び出します。サービスの結果に応じて、次に表示するViewと出力値を設定します。
JAX-RSではView層に関する取り決めは特にありません。フォームやJSON、XMLなどの任意のデータ形式が使用できます。入力データは、Controller層のリソースというオブジェクトに渡ります。JSF同様、Model層のサービスを呼び出した後、クライアントに返すデータをHTML、JSONなどのデータ形式で出力します。
Model層内のサービスは、ビジネスロジックの実装と、DAOを使ったデータベースとの連携を責務としていて、トランザクションの起点にもなります。DAOはJPAを使用してデータを永続化し、JPAはテーブルに対応するエンティティオブジェクトと、エンティティを操作して永続化を行うエンティティマネジャーによって構成します。
CDIは上記に登場する各オブジェクトの生成や依存性注入、ライフサイクルの管理、トランザクション制御を行います。
なお、Java EEアプリケーションを実行するためには、Java EE仕様を実装したアプリケーションサーバーが必要です。無償のものでは、GlassFishやWildFly(旧JBoss Application Server)、商用製品ではOracle WebLogicやIBM WebSphereなどが該当します。
Spring Framework
Spring Frameworkとは
Spring FrameworkはJava製のOSSフレームワークです。軽量かつ開発のしやすさから人気を得ています。特徴は、DIとAOP(アスペクト指向)を中核とした豊富な機能です。ドキュメントも豊富で、多数の採用実績があり、Javaに関するもので最も成功しているオープンソースプロジェクトと言ってよいでしょう(本連載では2015年5月時点で最新である、Spring 4.1.6、およびSpring Boot 1.2.3を使用します)。
以下は、Spring Frameworkで一般的に使われている機能です。
- コア機能 - Spring BeansによるDI機能やAOPによる横断的な処理などを提供する
- データアクセス機能 - 宣言的トランザクションや、データベース、NoSQLなどさまざまな永続化装置へのアクセスを行う
- Web機能 - Spring MVCなどのWeb用フレームワークを提供する
Spring FrameworkはJava EEよりも広範な機能を備えています。NoSQLやクラウドへの接続、Twitterなどの特定のサービスとの連携などは、その好例です。テスト用APIやデータマイグレーションなど開発効率を向上させる工夫にも富んでいます。最新技術にも素早く追従しており、さまざまなシステムで活用できます。
Spring Frameworkのアーキテクチャ
一般的なWebシステムでは以下のような要素を使います。
- Spring Boot - ライブラリ依存の解消と開発環境や実行可能ファイルの作成
- Spring本体 - DIの設定
- Spring Web MVC - MVCモデルのWebフレームワーク
- Spring Data JPA - JPAによるリポジトリの提供
データベースアクセスを行う方法は、JPAの他にも用意されていますが、今回はJPAを中心に説明します。アーキテクチャは以下のようなイメージです。
View層では、「Thymeleaf」というテンプレートライブラリで作ったHTMLを使用します。Viewの入力値は、Controller層のコントローラーで受け取ります。入力値にはフォームの他、JSONやXMLも使用できます。コントローラーは、Model層のサービスを呼び出し、その結果に応じてViewとデータを設定します。Viewの代わりにJSONやXMLなど任意のデータを出力することも可能です。
Model層内のサービスは、Java EEのサービスと同じ役割を担っており、トランザクションの起点として機能します。リポジトリは、Spring Data JPAが提供するデータ操作用のオブジェクトです。リポジトリとエンティティを使用してデータベースを永続化します。
各オブジェクトの生成や依存性注入、トランザクション制御は、SpringのDI機能が実現します。
Play Framework
Play Frameworkとは
Play Frameworkは、MVCモデルを採用したOSSの軽量Webフレームワークです。Java EEの標準に準拠せず、Webに特化した独自のAPIと開発環境を備えています。Java EEやSpring Frameworkと比較すると構成はシンプルです(本連載で使用するPlay Frameworkは、2015年5月時点で最新のPlay 2.4.0です)。
Ruby on Railsのような他言語のフレームワークの優れたポイントを取り入れ、開発効率と生産性を高めている点が特徴です。具体的には、以下のような仕組みが最初から用意されています。
- サーバー起動中でもソースコードの変更を再起動なしで反映する
- 設定ファイルやViewがコンパイル対象であり、可能な限り実行時エラーを防いでくれる
- コンパイルエラーや設定ミスなどを表示する分かりやすいエラー画面
- ユニットテスト用の仕組み
- データベースのマイグレーション機能
- ブラウザーベースの開発環境
これらの仕組みは、Java EEやSpring Frameworkにはデフォルトでは用意されていません。ライブラリやIDEのサポートで賄うことはできますが、それらの設定作業が必要となるため、手間が掛かります。開発スピードを重視する企業やJava以外の開発者を中心に人気を集めています。
なお、開発を行う言語は、JavaとScalaのどちらかを選択します。今回は、Java用のAPIのみを取り上げ、Scala用のPlay Frameworkについては割愛します。
Play Frameworkのアーキテクチャ
アーキテクチャは以下のようなイメージです。
テンプレートから作成したHTMLをViewとして使用します。入力値は、Controller層のアクションに渡します。フォームの他、JSON、XMLなどの任意の形式が使用可能です。その後、Model層のサービスを呼び出し、結果に応じて次のViewとデータを設定します。JSON、XMLなどのデータを出力することも可能です。
Model層内のサービスでは、ビジネスロジックの実装とトランザクション制御、データベースへのアクセスを行います。「EBean」はPlay Frameworkで提供されるO-Rマッパーのライブラリです。EBeanはJPA形式のエンティティを使用して、永続化を行います。なお、EBeanの他にも複数の連携手段が用意されています。
3つのフレームワークの総括
ここまでで、3つのフレームワークについて、概要や特徴を紹介しました。最後に、それぞれが、どのようなシステムに向くかを述べておきます。
Java EE
安定度を重視するシステムや大規模なシステムに向いています。Javaの標準であること、更新間隔が長いことなどが理由です。数多くの標準仕様があるため、プロジェクトに合わせて取捨選択すべき点は長所であり、短所でもあると言えるでしょう。
なお、Java EEを使ったシステムを動かすには、仕様を満たすアプリケーションサーバーが必要です。仕様を完全に満たす製品は限られているため注意してください。また、アプリケーションサーバーの構築作業も必要です。
Java EEには、JMSによるメッセージング、JTAによる分散トランザクション、JAX-WS・JAX-RSによるWebサービス、EJBによるリモート呼び出しなど、分散処理のための仕組みが用意されています。また、これらの仕組みに対応した製品も多数あります。周辺システムとの連携を考慮する必要がある場合、これらの仕組みに対応した製品を用いることで、システム間の連携を行うことが容易になります。
Spring Framework
開発効率を重視する場合や最新技術を使用したい場合に向いています。Spring Bootの登場によって必要な機能だけを選択して開発することが簡単になりました。OSSとしての歴史も長く、ドキュメントも豊富です。Pivotalによって開発がサポートされているため、開発が終了する可能性は低いと言えるでしょう。
実行環境の面では、Java EEよりも多くの環境で動作させることが可能です。Java EE仕様を満たさないTomcatのようなサーバーでも動作しますし、サーバーがなくても動作させることも可能です。また、クラウド上の動作もサポートされています。
Play Framework
迅速にWebアプリケーションを開発したい場合や、小規模な開発に向いています。導入が簡単なことや機能がシンプルであることが理由です。また、Typesafeによって開発がサポートされているため、開発が終了する可能性は低いと言えます。
Play Frameworkを導入したデフォルトの状態で開発に必要なツールはほとんどそろっているため、開発効率は最も優れています。設定ファイルやアノテーションが少なく、型安全を強調しているため、コードの見通しや保守性も優れています。JVMがあればどこでも動作するため、クラウドを含め、幅広い環境で動作します。
ただし、内部的にScalaを使用しており、Spring Frameworkと比較すると実績が少なめです。トラブルが起きた際は解決にコストが掛かる可能性があります。また、Javaの標準に準拠していないため、周辺システムと連携する場合は方法を考慮する必要があります。
次回は、画面作成や画面遷移について
今回は、Struts 1を使い続けることの問題点について記述し、その上で今後有力と考える3つのフレームワークを紹介しましたが、いかがでしたでしょうか。次回は、画面作成や画面遷移の機能を中心に、これらの違いについて解説します。
筆者紹介
前多賢太郎
ウルシステムズ シニアコンサルタント
金融系を中心に多数のシステム設計、構築を担当してきた。現在は顧客企業の若手社員を対象とした技術指導や、システム構築プロジェクトの技術支援を担当している。
「Enterprise Geeks」ではJava EEの記事を執筆中。
ここ最近の興味は、ドメイン駆動設計と関数型プログラミング。
Copyright © ITmedia, Inc. All Rights Reserved.
関連記事
- Struts後時代のJava EE/Javaモダン開発はどうあるべきか〜JJUG CCC 2014 Springまとめリポート(前編)
Java EEにおいてJava 8はどこまで利用できるのか、Java開発でGit、CI、継続的デリバリは、どこまで有効なのか、Struts後時代のJava EE開発における有効なフレームワークなどをお伝えする。 - 日本の開発者コミュニティが次世代Java仕様策定に貢献、Lambdaを手に入れたJavaテクノロジのその先へ
2015年4月8日、Javaテクノロジに関する開発者イベント「Java Day Tokyo 2015」が開催された。基調講演で紹介されたJavaテクノロジに関する話題を解説していきたい。 - Java 8時代の開発者のためのデバッグ/トラブル解決の基本・応用テクニック〜JJUG CCC 2014 Springまとめリポート(後編)
Java開発における3大トラブルと対策、IDEのデバッガー活用の必要性、Java 8より導入された新しいメモリ領域を使いこなすためのテクニック、独自のトランザクショナルメモリ機構を実装した有効性などをお伝えする。