Java EEの過去
Java EEには過去2回のエポックメイキングと呼べる技術の登場がありました。最初はEJBです。EJB以前はサーブレットを中心としたシンプルなWebアプリ開発のフレームワークでした。EJBの登場によりフルスタックで重厚なJ2EE時代に入りました。
次がCDIです。CDIはDI(Dependency Injection)のための規格です。少し時間差がありますが、CDIはJ2EEからJava EEへの名称変更の象徴です。
Java EEの現在
Java EEの現在の最新バージョンは7です。
原則論で言えば、Java EEのバージョン番号はJava自身(Java SE)のバージョン番号と同期しています。つまり、Java8の登場に合わせてJava EEのバージョン8もリリースされるはずです(ちなみに同じバージョンの組み合わせが必須という意味ではありません)。しかし、Java8のリリースから2年以上経った今でも、バージョン8はまだ出ていません。下手をすると、Java9のほうが先にリリースされそうなのが実状です。
Java EE 8のリリースの遅れから、一部にはJava EEの将来を心配する声もあがっています。そんな声の現れとして、Java EEの未来を危惧する人たちによるJava EEガーディアンズという行動が起こされています。このままOracle社に任せていてはJava EEの開発が進まないと心配している開発者によるコミュニティです。
今すぐにOracle社がJava EEを放り出す可能性は低いかもしれませんが、開発の中心がコミュニティに移っていく可能性はあります。個人的には、開発がコミュニティ中心になるシナリオはそう悪い話でもないかと思っています。しかし、現実を見据えると、お金の匂いが開発継続に重要であることは否定できない事実です。
Java EEの未来
そんなJava EEですが、今後どこに向かうのかを占うのはそんなに難しくないと思っています。なぜなら最近のJava EEは、先行するSpring Framework(以下Spring)を追いかけているからです。
Springが、DIとAOP(アスペクト指向プログラミング)で一世を風靡してから実に10年以上経っています。Springは、J2EE 1.4からJava EE 5への大転換に多大な影響を与えました。冒頭、ふたつ目のエポックメイキングな技術として紹介したCDIは、SpringのDIから影響を受けた標準規格です。
Springの最近のキャッチフレーズはマイクロサービスです。つまり、Springを追いかけるJava EEも、マイクロサービス対応を標榜する可能性が高くなっています(既にやや非公式ながらもそのようなメッセージは漏れ伝わっています)。
EJBからマイクロサービスを想う
何がマイクロサービスなのか、には諸説あります。マイクロサービスというキーワードの登場初期は、SOA(サービス指向アーキテクチャ)と何が違うのか、と叩く向きもありましたが、今となってはSOAの設計パターンのうち、成功したひとつのパターンがマイクロサービス、というぐらいの位置づけで良い気がします。
個人的に興味深いのは、マイクロサービスとEJBの比較です。EJBの目指していたのは分散オブジェクトでした。過去形にしたのは、失敗だったと断言してもいいと思うからです。かつてのEJBの分散オブジェクト時代、Webアプリ(サーブレットアプリ)の背後にEJBコンテナを配置し、EJB側にビジネスロジックやデータアクセスを記述し、Webアプリ側をビジネスロジックと疎結合にしろ、がEJBの哲学でした。
RESTで応えるマイクロサービスとEJBのリモートオブジェクトには奇妙な相似性があります。
皮肉なことにSpring創始者のロッドジョンソン氏はEJBのリモートオブジェクト批判の急先鋒でした。批判のポイントはいくつかありますが、今でも成立しそうな批判ポイントを3つあげてみます。
- ① 分散オブジェクトはテストが無駄に複雑化する
- ② 分散オブジェクトは配備(デプロイ)が大変になる
- ③ リモートオブジェクトのアクセスはオブジェクト指向の良い設計を壊す場合が多い
最後の指摘は少々わかりづらいので補足します。リモートアクセスはネットワークを介すため、ローカル(同一VM内)のメソッド呼び出しに比べて、どうしても遅延が発生します。開発者がこの遅延を嫌い、呼び出し回数を減らす意図でのメソッド設計になりやすいという危惧です。この結果、本来あるべき、直交性の高いメソッド設計から乖離するリスクを指摘しています。マイクロサービスでも、なんらかの集約API(リモートアクセスの呼び出し回数を減らすためのラッパーAPI)は不可避なので、かつてのEJB批判の一部には、マイクロサービスの時代にも耳を傾ける価値があります。
EJBと類似しているからマイクロサービスがダメだ、などと主張する気はありません。むしろ、個人的な主張は分散システムこそが正義だと思っています。ただ分散システムには、本質的な難しさが内在しているのも事実です。
EJBからマイクロサービスへの飛躍
EJBの時代からマイクロサービスへの変化は大きくふたつあります。ひとつは障害に対する考え方の変化です。マイクロサービスでは、個々のサービスのインスタンスが落ちる前提で設計します。システムの一部が死んでいても、その影響を隔離してシステム全体は生き続けるように設計します。また、インスタンスが落ちたら、さっさと別のインスタンスを上げてしまえばいいという発想もします。ある意味、クラウド時代ゆえの考え方です。
マイクロサービスのもうひとつの変化は分散データベースです。個々のマイクロサービスは、(少なくとも論理的には)個々のデータソースを持ちます。2PC(2フェーズコミット)のような形でマイクロサービス間のデータの一貫性を取る考えはありません。(古典的な)分散トランザクションがEJBのひとつの技術要素だったことを思うと象徴的な変化です。
古典的な分散トランザクションを捨てた世界に待つのは、NoSQLなどで有名になった結果整合性です。筆者自身は、NoSQLを身をもって実践しているので、結果整合性でも大丈夫と安易に言う気にはなれませんが、インターネットスケールの大きなシステムでは、全体とは言わないまでも一定の割合で必須になる考えです。
Java EEとの向き合い方
Java EEの過去から未来を徒然なるままに話してきました。最後に開発者はどうJava EEに向き合うべきかの個人的見解を述べてみます。
Java EEがJavaでWebアプリを作る時のフレームワークのひとつの選択肢であるのは間違いありません。J2EE時代(EJB時代)は重厚なフレームワークでしたが、今は現実的な選択肢のひとつです。
もうひとつ、Java EEにはアーキテクチャの勉強のための価値があると思っています。Java EEには長い間に渡る頭の良い人たちの考えが詰まっています。オブジェクトのライフサイクル管理や状態管理、並行制御、トランザクション管理、例外処理、非同期処理、どれも本質的に複雑です。しかし、一定規模のシステムを作る時、これらの複雑さは避けられません。これらの複雑さをどう抽象化するかが設計の肝になります。そんな時、Java EEの抽象化を学ぶ価値があると思います。