ModernJavaEEDesignPatterns / History of Java EE


JavaEE の歴史

内容

“Develop once, run everywhere!” プログラム言語 Java が開発者にもたらした約束は、主要なフォースとなって多くの成功をもたらしてきた。 興味深いことに、Java はより広範囲に受け入れられながら、安定したエンタープライズアプリケーションからのニーズも高まっていった。 インターネットと最初のWebブラウザが発明されたことによって、Java で実装された最初のWebサーバーは、やがて Servlet および JSP として仕様化されることになった。 これらの仕様がその後 Java 2 Enterprise Edition (J2EE) の基礎となった。 1999年から2003年にかけて、Java Specification Requests (JSRs) の数は 10 から 18 に増加した。 そして2006年、J2EE は Java EE と名前を変えることになった。 この名称は現在も継続しており、最新バージョンを表す数字を末尾につけるようになっている。 本書の執筆時点では、最新バージョンは Java EE 7 (JSR 342) であり、2016年の年末には Java EE 8 (JSR 366) がリリースされる予定である。

エンタープライズ業界は早い段階から Java EE を受け入れていた。 Java EE のもたらす約束にはたくさんの利点があるからだ。 中央集権的な構造、スケーラビリティ、トランザクション管理、標準化されたプログラミングモデル、高いスループット、安定した運用性など。 だが、一つ一つの約束に難しい課題があり、運用および開発におけるパフォーマンスを約束した仕様が実現されるまで、待たされることになった。 ベンダーおよび顧客の双方にとって、新しいバージョンが提供されるのはゆっくりとしたもので、未だに Java EE 5 ベースで構築されたアプリケーションが散見されている。 中には、2006年の中頃にリリースされたものすらあるようだ。

Mistakes We Made

伝統的な Java EE アプリケーションは、書籍「Core J2EE Patterns」に記載された中心的なパターンによって支えられている。 プレゼンテーション、ビジネス、インテグレーションという3つの主要なレイヤに分割されているのだ。 プレゼンテーションレイヤは Web Application Archives (WARs) としてパッケージングされる。 そして、ビジネスロジックとインテグレーションのロジックは、個別の Java Archives (JARs) としてパッケージングされる。 これらをデプロイ単位として統合したのが、Enterprise Archive (EARs) だ。

Java EE に関連するテクノロジーやベストプラクティスは、うまく設計されたモノリスを構築するには十分なものだった。 しかし、ほとんどのエンタープライズなプロジェクトではアーキテクチャに対する視点を見失っている… 初期の Java EE アプリケーションの概要を Figure 2-1 に示す。 構築に携わった人たちの技術的なケイパビリティを示すものではないが、現場で培った経験を反映しているものと考えてよい。

この手のアプリケーションは、アプリケーションサーバーや負荷分散装置のインスタンスを増やすことで性能を拡充することができる。 アーキテクトが再利用性のことを考えていたとしたら、あらゆるエンタープライズアプリケーションで利用できる共通の JAR やライブラリを用意したかったはずだ(XXX)。 シングルサインオン (SSO) のような横断的関心事はエンタープライズアクセス管理(EAM) ソリューションが提供する。 そして他にも、ロギングや監視、データベースなどが中央集権的な構造が提供する。

小さな変更をするにしても全てが密に結合、統合されているおかげで、アプリケーションのテストは最初から最後まで極めて慎重にならざるを得ない。 新しくリリースしたアプリケーションが日の目を見るには、1年から2年かかってしまう。 アプリケーションはプログラム以外にさまざまな要素から構成されていた。 数えきれないほどのやデプロイ記述子、サーバー設定ファイル。それに加えてサードパーティコンポーネントの設定など。

開発チームもモノリシックアーキテクチャに毒されていた。 数ヶ月におよぶテストサイクルがその証拠だ。 その上、5年以上継続しているプロジェクトは、大量の不具合を抱えているし、データベースにもさまざまな機能を抱え込んでいた。 それだけでも大変なのに、テストによる品質保証は不足している状態だった。 受け入れテストがない、明文化されたビジネス要件がない、設計とユーザービリティに明確な区別がない。

この手のエンタープライジーなプロジェクトを進めるには複数の開発チームと、そのチームを監督するためのたくさんの人間が必要だった。 ソフトウェアの設計という観点からすると、アプリケーションには技術的なレイヤリングが多すぎる。 ビジネスコンポーネントやドメインは、既存のデータベース設計や古くなったビジネスオブジェクトの定義に追従していることがほとんどだ。 私たちの業界はこれらの教訓から学ばなければならない。 自分たちで築き上げたモノリスをただ維持するのではなく、新しいパラダイムやメソドロジーも取り入れて、より良くしていかなければならない。

Evolution Continues with ESBs

ビジネスを中心に据えた設計が発展するにつれて新しいテクノロジーが生み出されてきた。 そして、サービスを中心とした組織構造への移行が広がっていた。 エンタープライズサービスバス (ESB) は、中央集権的な構造の上に、再利用性と相互互換性をもたらすものだった。 多くのベンダーによって喧伝された結果、既存のモノリシックアプリケーションの中でも最上のものとして認識されるようになった。

あらゆるアプリケーションは、交換可能なサービスへ対応するには、分割し、再構築しなければならない。 サービス指向アーキテクチャ (SOA) という新しいパラダイムがその背景にある。 インターフェイスとしてWebサービス (WS) が選択されることが多かったのは残念なことだ。 Webサービスは、XML 形式に変換したデータを、Simple Object Access Protocol (SOAP) によって送信するものだ。 Webサービスに対応するため、ほとんどのプロジェクトが膨大な量のコードと記述子を追加することになった。

どの ESB 製品も専用のツールを必要としていたし、ツールがなくても使用できるのはせいぜい2製品くらいのものだった。 コードベースは肥大化し、アプリケショーションを連携させるには IDE の機能を拡張しなければならないことを開発者は学ぶことになった。 連携可能にするということは、当初のプロジェクトを開発途上に戻して、新たなコーディングを必要とすることになったのだ。

関連するエンドポイントのプロトコルやシリアライズ方法を切り替える代わりに、それぞれの ESB 上の経路は変換器としての役割を果たすようになるだろう。 ESB に新しい変換手法とルーティング手法を導入するということは、無視できない程度の複雑性をもたらすことだろう。 かつてモノリシックなせいでテストが困難であった状況は、分散システムの特性が加わることで更に悪化することになった。 分散性それ自体は致命的なものではないが、複雑な依存関係が生まれてしまうことは深刻な問題となる。 ESB のルーティングや変換ロジックを少し変更しただけで、全体に大きな影響を与えてしまう。 それぞれの環境に配置された ESB の設定を変更することすら、やがては不可能になるだろう。 以前に、バージョニングの問題として考えたことのある問題だ。

テクノロジーが進化し、ベストプラクティスが洗練されていくと、運用には最大級の影響が生じることになる。 分散アプリケーションには状態監視が必要だ。利用できるリソースや要求される性能に応じてスケールすることが何よりも重要だからだ。 文章にすると簡単だが、システムを構成するために必要な全てが独立したコンポーネントとしてそろっていなければならないし、 それらを実行するためのOSやリソースも必要になる。 単一インスタンスのアプリケーションサーバー、あるいは、クラスタで実行するアプリケーションサーバー。 それぞれが複数のWebサービスを実行する。 これら全てが ESB をスケール可能とするために必要なのだ。

これらの環境を統制するには、完全に統合されたプラットフォームと、高価で専用の状態監視ソリューションが必要だ。 近年の ESB 製品は、過去の共有データモデルの経験を反映したものになっている。 ビジネスプロセスは第一級のアプリケーション設計要素となり、関連するドメインオブジェクトなどの様々な属性を持つようになっている。 業務の定義を完全なものとするため、顧客エンティティはたくさんの属性を持つようになった。 一つのアプリケーションでいくつもの関連ユースケースを処理する代わりに、そのようになったのだ。 要するに、私たちが学んだのは、データを分割することこそが成功に欠かせない要因であるということなのだ。

Challenges and Lessons Learned

これまでに、エンタープライズプロジェクトではさまざまなレベルで挑戦が行われてきたことがわかっただろう。 また、10年前から5年前にかけてこの業界にどのような革新があったのかもわかっただろう。 技術的な挑戦がたった一度ではなかったことは明らかだ。 第一人者が複雑性の問題に習熟し、パターンとベストプラクティスを再構築するにはある程度の時間がかかるだろう。

それとは別に、私たちの業界はプロジェクトマネジメントを手なずける方法についても学ばなければならない。 すでに新しいプロジェクト管理手法が広く受け入れられている。 それは、反復、あるいは、アジャイルなアプローチと呼ばれるものだ。 チーム体制や要件の粒度をより小さくすることが求められるし、それによってより頻繁な変化が導かれるのだ。 つまり、どんどんテストしてどんどんリリースするようになるのだ。 ソフトウェアリリースプロセスにおける自動化や頑健性は、すぐに受け入れられるプラクティスとなるであろう。 たとえ柔軟性を欠いたエンタープライズプロジェクトであっても、新しいフィーチャを素早く提供できるようになるだろう。


DevOps?: Highly Effective Teams

一方、ソフトウェアのデリバリーがうまくいくには運用と開発が密に協力することがとても重要だ。 頻繁な変化と高度に自動化された仕組みによって、別々に管理されている環境へのデプロイメントは数え切れないくらい行われるようになるだろう。 デプロイプロセスの難しさが顕在化するのは当然のことだ。 これこそが、DevOps? という考え方の生まれた背景だ。 DevOps? 運動の中心にあるのはチーム文化だ。 開発者、運用担当者、その他のIT専門家による共同作業、および、コミュニケーションを促進することを目指している。 組織が高品質なソフトウェアをリリースするための基礎となるのが自動化とツール化だ。 DevOps? には、チームが頻繁な変化を embrace するために必要なコミュニケーションのための方法論も明記されている。 開発チームはコードを書くだけでなく、DevOps? の流れにのせることにも責任を負うのだ。

Microservices: Lightweight and Fast

中央集権型コンポーネントはもはや理想的とは言えなくなっている。 冗長なプロトコルやインターフェイスと同時に、重量級のアプリケーションサーバーについても再考する時期がきたようだ。 以前とは逆に、技術的な設計目標は扱いやすいアーティファクトやサービスを目指すようになってきている。 それは、SOA や ESB を基盤とするプロジェクトにおけるほぼ全てのサービス実装として実現できないことが証明されているものだ。 マイクロサービスは、高度なルーティングや変換処理を、単純なルーティングとエンドポイントにカプセル化したロジックによって実現する。 マイクロサービスという名前にはそのサイズが小さいことも意味しているが、もちろんそれだけではない。

マイクロサービスは一つのビジネス要件を実現することが目的になっている。 最も効率よくマイクロサービスを実行する環境として、必ずしも成熟したアプリケーションサーバーは必要ない。エンタープライジーな設定に悩まされるしね。 ただのサーブレットエンジン、あるいは、JVM だけで十分だったりする。 実行環境の種類が増え、さまざまなプログラミング言語が使われるようになるというのは、運用部門にとっては頭を抱えたくなる状況だ。 Platform as as Service (Paas) は一番優れたソリューションだとされてきたが、 次世代のエンタープライズアプリケーションにとっては、何らかの新しいテクノロジーが構成要素の一角を占めることだろう(XXX)。

Containers: Fully Contained Applications

すでに稼働しているサービスを実現しているプログラミング言語や実行環境を、運用部門が完全にはサポートできないのだとしたら、何らかの手段を持ってそのギャップを埋めなければならない。 コンテナ化は、言語や実行環境の専門家を調達することの代替手段となるだろう。 コンテナとは、仮想化レイヤをOS上のアプリケーションとして提供するものだ。 OSのカーネルは、ベアメタルサーバー上の独立したゲスト仮想マシン上で実行される。 ゲスト仮想マシンがコンテナと呼ばれる。

究極的には、アプリケーションと関連するミドルウェアやその設定も含めてビルドやテストをすること、そして、配置をすること、あるいは、支援するツールを提供することが開発者に求められるようになるだろう。 よいニュースもある。 プロジェクトはもはや中央集権型の基盤に依存しなくなる。 運用部門にとっても、以前と同じように本番環境への移行できる。

Public, Private, Hybrid: Scalable Infrastructures

プロジェクトを開始すると、いくつもの環境が必要になる。 ちょうど前に説明した変化というものが、運用にかかる費用をうまく減らしてくれるわけではない。 それどころか、DevOps? やコンテナ化機能を実現するには、さらに多くの時間をかけなければならないだろう。 これは、クラウドインフラの需要が未だに広まり続けていることに対する最も説得力のある根拠と考えられる。

いくつもの同じインスタンスを実行するのに、仮想化機能は費用対効果に見合うものであることは証明されているが、 仮想化機能を実行しているハードウェアへの結合度を下げたり、管理したりすることは決して容易なことではない。 実際のところ、プロジェクトの都合に合わせてスケールできるようにしなければならないし、それぞれのインスタンスにコストがかかることになる。 プロジェクトでその費用をまかない、運用していかなければならない。

クラウドインフラの変更はとても素早い。 使った分だけ費用を払えば、すぐに利用できるようになるのだ。 ちょっとまで、クラウドプラットフォームはコンテナ技術の発展によって、そのケイパビリティを広げてきた。 以前ならアプリケーションサーバーやデータベースサーバーのインスタンスを起動していたものだ。 今では、ほとんどのプロダクトがソフトウェアスタックをコンテナで定義、実行できるようにすることで、プロジェクトで利用するための柔軟性を実現している。 それも、効率的な運用のための管理容易性を保ちながらだ。

前述した方法論やテクノロジーによって導かれる帰結を Figure 2-3 に示す。 この図は、近代的なエンタープライズアプリケーション開発に必要な要素を積み上げたものだ。 また、システム開発の将来像に欠かせない土台を表している。 以降の章では、それぞれの要素についてより詳しく見ていく。

担当者のつぶやき


みんなの突っ込み