この投稿は Java Advent Calendar 2011 の2011年12月27日担当分として新たに書き下ろしたものです。
Java SE 6 (Mustang) のEOL (End Of Life) まであと半年となりました。鎮魂歌(レクイエム)と言うには時期尚早な気もしますが、Java SE 7が登場するまで約6年という長きにわたってJava SEを牽引してきたこのバージョンについて、その生い立ちを含めてお話ししようと思います。
1. Java 2 SE 5.0 (Tiger) が果たせなかった夢
2004年9月に登場したJava 2 SE 5.0 (Tiger) により、Javaプログラミングは一変しました。このバージョンの新機能は、それまでのJavaプログラミングの常識を覆すようなものでした;
- 総称型
- アノテーション
- オートボクシング・アンボクシング
- 並行処理ユーティリティ
- 管理ツールの改善(JConsole、JMX対応など)
新たに追加された多数の新機能はどれもプログラミングのしやすさを大きく改善するものでしたが、一方で AWT/Swingをはじめ既存のAPIの多くはあまり改善されませんでした。
それらの改善は、次のバージョンであるMustang、すなわちJava SE 6に託されることとなりました。
余談ですが、SunとApache Software Foundationが本格的に対立し始めたのもこの頃です(最終的にASFはJCPを去ることになります)。
2. Java SE 6 (Mustang) の特徴
2006年に予定より少し遅れて登場したJava SE 6 (Mustang) は、当初の構想ではJ2SE 5.0同様に言語仕様の変更を含む大きなアップデートとなる構想でした。しかし、言語仕様の変更を伴う改修は次のバージョン(コードネームDolphin)以降に持ち越され、最終的にはJ2SE 5.0と同一の言語仕様で、細部の改善が中心という地味なリリースに落ち着きました。
Java SE 6の改善点は、ひとつひとつはJ2SE 5.0の変更よりも小規模なものですが、修正点の数では驚くほど多岐にわたっています。ここではすべてを紹介するのは難しいので、代表的なものに絞ります。詳細は下記URLを参照してください。
まずJava SE 6ではAWT/Swingはパフォーマンスを含め全面的に見直しが行われました。AWT/Swingの高速化はJ2SE 1.4の頃から少しずつ行われていましたが、API自体もJava SE 6で改善されました。特にSwingでは新しいレイアウトやマルチスレッド対応、細部にわたるAPIの使い勝手の改善など、プログラミングのしやすさが格段に向上しました。
APIの改善はAWT/Swingに限らず、コアAPIについても行われています。どれも今までありそうでなかった機能です。例えばString.isEmpty()メソッド、文字列が空であるかどうかを判定するだけのメソッドですが、こんな基本的なメソッドでもそれ以前のJava SEには存在しませんでした(Java Collection Frameworkには当初から存在していたという不思議...)。配列の扱いも改善され、Arraysクラスが本格的に総称型対応を行うことで生まれ変わりました。配列のコピーは、古くて使い勝手に難のあるSystem.arraycopy()メソッドを使うか、独自にループ処理でコピーを行う必要がありましたが、Java SE 6ではArrays.copyOfRange()メソッドの呼び出しだけで済むようになりました。その他、Calendarの和暦対応など、トリビア的な変更まであります。
次に、JAX-WS対応とそれに伴うXML処理の大幅な改善です。まず、Java SEがXMLパーサーを内包したのは大きな改善点です。Java SEではXMLパーサーのインタフェースは定義されていましたが、実装は別途用意しなければなりませんでした。それがJava SE 6からは何もしなくてもXMLパーサーが使えるようになったのです。パーサー自体も従来からあるSAX、DOMの他に、高速なStAXが追加されています。StAXは国内のプログラマーにはあまり馴染みがないようですが、既にJavaFX 2.0のFXMLのパース処理に採用されるなど積極的に使用されています。また、JAX-WSとともに追加されたJAXBよりXMLとJavaBeansの相互変換も出来るようになりました。Java EEとJava SEの双方に含まれるようになったJAXBは、今やWebサービスの実装(Java SE/EEのJAX-WS、Java EE 6以降のJAX-RS)において必須のものとなっています。
そしてJava SE 6では、JavaからJavaScriptが呼べるようになりました。より正確には、Java VM上で各種スクリプト言語が実行できるようになったのです。これによりJRubyやScala、Groovyなど多くのJava VM上で動作する実装系が生まれ、それらの開発者(特にJRubyの開発チーム)からのリクエストによりInvokeDynamicと呼ばれるJava VM上で動作するスクリプト言語のパフォーマンスを劇的に改善する機能がJava SE 7に追加されました。その源流が、Java SE 6から発生したのです。
参考まで、Java SE 6のJavaScript実行エンジンはRhinoと呼ばれていますが、Java SE 8ではRhinoの代わりにInvokeDynamicを用いて実装した新しいJavaScript処理系(Nashorn)が含まれる予定です。
最後に、Java SE自身が持つ管理ツールもアップデートされています。JConsoleの機能向上やJMX対応の改善などです。また、HotSpot VMもJ2SE 5.0よりさらに高速になっています。言語仕様の変更こそ行われなかったものの、Java SE 6の変更点は多岐に渡り、Java SEを成熟させるものとなりました。
3. OpenJDK と Java SE 6
Java SE自体をオープンソース化するという案は、Java SE 6リリースの頃から出ていました。当初はSun Microsystemsの管理下に置かれた限定的なプロジェクトでしたが、最終的にはOpenJDKというオープンソースプロジェクトの設立という形で落ち着きました。
OpenJDKプロジェクトはJava SE 6のリリースよりいくらか遅く、SunがOpenJDKに対してJava SE 6のリリースを寄贈することで本格的にスタートしました。もっとも、プロジェクトの流れとしてはOpenJDK6の成果をJDK6にフィードバックするのが中心であり、OpenJDKがJava SEを置き換えることはありませんでした。ただし、これはJava SE 6までの話で、Java SE 7以降はOpenJDKをJava SEのリファレンス実装として取り込むプロセスが確立します。
それまで実質的なクローズドソースであったJava SEがオープンソース化に踏み切ったことにより、少なくとも品質の向上という点では(テスターの数が圧倒的に増える分だけ)有益であったと考えます。その一方で、ライセンスに関わる諸問題を抱えることにもなったのです。
OpenJDKのライセンスは一般にGPLと認識されています。ただし厳密なGPLではなく、クラスパス例外付きGPLと呼ばれる、動的リンクに関する制約を緩めたGPLの派生系です。似たようなライセンスにJBoss等が採用しているLGPL (Lesser GPL) が存在します。
4. Java SE 7 の難航と Java SE 6 の強化
Java SE 6 (Mustang) が発表されたと同時に、Mustangの次のJava SEとしてDolphinも発表されました。後にJava SE 7となるバージョンで(Dolphinというコードネームは後になくなってしまいましたが)、2008年頃のリリースを予定していました。これはJavaのメジャーバージョンアップが約2年ごとに行われてきたことと合致します。
Java SE 7では言語仕様の強化を含む大規模なアップデートを予定していましたが、クロージャ採用の可否を巡り仕様が二転三転した挙げ句、クロージャ(現在ではラムダと表記を改めています)を中心に予定していた機能の多くをJava SE 8以降に先送りせざるを得なくなりました。これは同時にJava SE 7リリースの大幅な遅延をも意味し(実際のリリースは2011年7月28日)、Java SE 6は予定よりも遙かに長い期間を現役であり続けることとなりました。
現時点ではJava SE 8、Java SE 9、Java SE 10をそれぞれ2年おきにリリースする構想となっています。Java SE 8は予定通りにプロジェクトが進行すれば2013年に登場します。
もっとも、Java SE 7で難航していたのは言語仕様とAPIであり、Java VMとツールの改良は順調に進んでいました。そしてJava SE 7の完成よりも前に、進化したJava VMとツール群のJava SE 6へのバックポートが行われています。以下に代表的な例を挙げましょう:
- Visual VM - Update 7より同梱。JDKとは別のプロジェクトで開発がスタートし、Java SE 7の管理機能の目玉として注目されていた、商用プロファイラに匹敵する高機能な管理ツール。当初は英語版の単体のみであったが、現在では日本語化され、GlassFish連携プラグインなどいくつかのプラグインを標準で同梱している。参考まで、最新のVisual VMとGlassFishを組み合わせることで、商用版GlassFishに匹敵するサーバー状態監視が可能になる(とは言え、JRockitの各種管理ツールを全面適用した場合には劣る)。筆者一押しのツールなので、使える状況下では積極的に使って頂きたい(ただし本番環境をプロファイリングするのはかなりリスキーなのであしからず...)。
- ConsumerJRE - Update 10より採用された新しいHotSpot VMで、Java KernelやQuick Starter等の高速化技術を導入することにより、主にアプレットの高速化を実現した。 サーバーサイドではこれらの新機能の恩恵は受けられないが、HotSpot VM自体が高速化しているため、相応のパフォーマンス向上が見込める。
- G1GC (Garbage First GC) - Update 14より試験的に実装。Java SE 7の標準GCとして採用予定の次世代GCで、並行処理を活用して設計された新しいアルゴリズムを用いる。並行処理が前提のため、単一コアCPU環境では、逆にG1GCが負荷になる可能性あるため注意が必要。もっとも、最近の潮流からマルチコアの普及が著しいが...。
※この記事を執筆している時点(Java SE 6 Update 30 / Java SE 7 Update 2)では、G1GCはいまだ試験的な実装という位置づけで、具体的にどのタイミングでデフォルト実装になるかは未定。現在もG1GCのチューニングは続いているため、利用する場合にはJava SE 6/7ともにできる限り新しいアップデートを推奨する。
※追記:G1GCは2012年5月にリリースされたJava SE 7 Update 4で正式サポートされた。このアップデートはMac OS Xへの正式対応を果たし、またそれまでの積み残しを一通り解決したことにより、Java SE 7本来の姿にようやくたどり着いたと言えよう。
これらは新しいバージョンが絶えずバックポートされており、新しいアップデートほど安定したものが含まれています。これは筆者の主観ではありますが、Java SE 6とJava SE 7のHotSpot VMや管理ツールは、Java SE 7で追加されたInvokeDynamic等の例外を除いてほぼ同等の実装になっているのではと推測されます。
5. Java SE 6 =Java SE で最も成功したバージョン
この記事の執筆時点(2011年12月27日)で、Java SE 6はUpdate 30に達しています。これは初版から28回のアップデート(Update 8および9はリリースされず)が行われ、絶えずバグフィックスが行われ、また言語仕様以外のレベルで新技術を導入した結果でもあります。なお、過去のJDK(Java for Businessを除く)において、単一のバージョンでここまでアップデートリリースを重ねてきたものはJava SE 6だけです。
※追記:2012年5月現在、Java SE 6はUpdate 31に達しており、またEOLも当初より約半年延長され2012年11月へと変更となった。ただし、メンテナンスは既にセキュリティFIXのみに限られたようで、G1GCのバックポートなど新機能の追加は行われないものと考えられる。
ところで、Java SE 6はどんな位置づけのバージョンだったのでしょうか。J2SE 5.0のマイナーチェンジとして主にAPIを中心にブラッシュアップを図った目立たないリリースであった一方、開発中だったJava SE 7の新技術を積極的にバックポートして実行環境(仮想マシン)としてのJava SE 6の品質と評価を高めました。結果、使い勝手の良いAPIと最先端のランタイムから構成された優秀なバージョンに仕上がったものと、筆者は考えます。特に6年間という長きにわたってJava技術の最先端を牽引し、Java EEやJavaFXがJava SE 6を前提に設計されていることや、Java VMベースのスクリプト言語が多数登場してきていることを考えると、極端な言い方ですが「Java SE 史上、最も成功したバージョン」と称することも出来るのではないでしょうか。
残念ながら、Java SE 7の仕様には、ラムダをはじめ、当初導入予定だった目玉となる機能がいくつもJava SE 8以降に先送りされました。またJava SE 7自身もリリース先行が仇となったのか、当初予定機能(パーマネント領域の廃止やG1GCのデフォルト化など)を実装できないままリリースしています。悲観的観測では、Java SE 6がEOLに到達しても、Java SE 7がまだ安定していない可能性すらあり得ます。
※追記:2012年5月にG1GCはリリースされ、デフォルト化も時間の問題と思われる。また、パーマネント領域廃止のための作業も着々と進んでいる。
筆者は、もし来年同じような執筆の機会が得られたとしたならば、Java SE 7について思うところを書き留めたいと考えています。そしてその時、今回Java SE 6へ贈った賛辞を、そのままJava SE 7に贈ることができることを、切に望んでいます。
2012-05-08 : Java SE 7 Update 4のリリースにあわせていくつかの追記を行いました(追記した個所については小さめのフォントと本文と異なる色を使用しています)。
コメントする