Mark Reinhold氏は jigsaw-devメーリングリストに,新たなHgフォレストへのリンクhttp://hg.openjdk.java.net/jigsaw/jake/を紹介するメールをポストした。JDKでモジュール機能を実現するため,Jigsawプロジェクトを再出発することがその目的だ。
Jigsawは長く続いているプロジェクトだ。当初はJSR 277,後にはJSR 294として,Javaのコアランタイムライブラリを別モジュールに分離することを目標にしていた。サーバサイドにおいて必要とされている,AWTのサポートを含まずに動作するJVMが,これによって始めて実現するはずだった。
JDK自体をモジュール化するのは簡単ではない。例えばjava.beans
パッケージはjava.applet
に依存し,java.applet
はjava.awt
に依存している。設計的判断が下されたずっと後になって,このような依存関係を取り除くのは,厄介という他にない作業だ。
Javaで利用可能なモジュールシステムは,実はかなり前から存在していた。JSR 8,近年はOSGi,あるいはJSR 291として知られるそのシステムは,主要なほとんどのJava EEアプリケーションサーバのみならず,今日では多くのシステムやアプリケーション(JIRA, Eclipse),さらにはバーティカルマーケットシステム(組み込みシステム,ホームオートメーション)でも採用されている。しかしながらJigsawは,java.util.Date
やJava IO NIO NIO2 NIO2.2,java.logging
などといったパッケージでの設計的成功例を踏襲しようとしている。性能的には劣るJDK独自のシステムを開発して,ベストプラクティスの無視を決め込んでいるのだ。(幸運にもJava 8では,奇妙極まるjava.util.Date
の修正版のさらに修正版として,Joda timeパッケージがjava.time
という名称で導入されることになった。)
JSR 277/Jigsawは,再出発する度にその対象範囲を狭くしてきた。当初はレゾリューションチェーンとリポジトリストレージ機構を備えた,汎用的なアプリケーション用モジュールシステムになるはずだった。(Javaであるから,これらはいずれもModuleFactoryやModuleResolveFactoryに通じる,プラグイン可能な構造であった。) 5年程前の2008年11月,JSR 277は事実上破棄された。適用範囲が見直され,スーパーパッケージの概念が導入された(JSR 294へと通じる)。いくつかのパッケージを集めて,外部にはひとつのパッケージあるいはAPIとして公開するものだ。
JSR 294が頓挫した頃,モジュールシステムの提供手段として誕生したJigsawプロジェクトは,JVM自体を主な目標としたものだった (他のアプリケーションでの使用も視野には置いていた)。JigsawはJavaでモジュールを定義するための基盤提供を目的としていたため,モジュールレゾルバチェーンなど,明らかに必要な機能を備えていなかった。Jigsawプロジェクトの大きな失敗のひとつは,モジュールの依存性を宣言的ではなく,実行コードに基づいて定義可能としたことだ – これによってモジュールシステムの動作可否に関する情報を,静的な解析で得ることができなくなってしまった。(制約の充足性が静的に検証不可能なモジュールシステムの一例は 'classpath` だ。現在でも小規模なJavaアプリケーションやIDEでは一般的に使用されている。)
1年程前,MarkはProject Jigsaw: Late for Train という記事で,JigsawがJava 8トレインから外れたことを発表した。このニュースには賛否両論の意見があった。OSGiの支持者たちはこれを勝利と主張し,反対者たちは敗北と呼んだ。いずれにしても,JigsawのソリューションをJava 9まで遅らせたことで,Jigsawの問題解決に向けた適切な判断が可能になるかも知れない。
再出発に際してMarkは,プロトタイプを公開したいと考えている。過度に手を拡げたものではなく,既存のレゾリューションエージェントがJARファイルを提供すると同時に,要素間の静的なモジュール依存性を生成する手段も提供できる,というようなものだ。現時点でのコードはJDK8からフォークしたもので,過去の負債を背負ってはいない。ただし,以前の試みで問題を発生させた設計上の決定のいくつかについては,改めて議論しなければならないだろう。
他の問題と合わせて私たちは,現在のプロトタイプのように特別な "モジュールモード" (狭い範囲ではあるが,これまでの動作とは深い部分で異なっている) の導入や,依存性の解決 (MavenやIvy, Gradleなどのビルドツールが十分に役目を果たしてくれる) をしないで済むかどうか,見極めて行きたいと思っています。
今回のプロトタイプの開発では,合理的な部分については古いコードも転用しています。ただし,以前の設計判断を再確認するチャンスも活用して,すべてをもっと明確にしていきたいのです。
設計的判断の必要な問題は,おもに次のようなものだ:
- セマンティックバージョニングなど既存のバージョンシステムを採用するか,独自にバージョンナンバを構築するべきか。
- モジュールシステムの依存性を(Ivy, Maven, Gradleのように)宣言的に表現するか,あるいは依存性を決定するためにコード実行が必要か (静的解析や事前検証が不可能になる)。
- モジュールシステムは(OSGiのように)動的か,あるいは(Mavenのように)静的か。言い換えれば,モジュールの取得と開放を行うのか,取得するだけか。
- 依存性メタデータはJVMが理解できるように.classファイルに格納すべきか,あるいはJSONやYAML,Mainfest.MFのようなテキストファイルにするべきか。
Oracleが外部開発のソリューションを嫌うため,Jigsawの開発ベースとしてOSGiが選択されることはありそうもない。ただし完全に動的なソリューションであるOSGiは,JVMのモジュール化という目的には機能過多とも言える。バージョン依存性とバンドルを備えつつ,動的性質を持たない(従って複数のクラスローダを持つ)OSGi風のシステムがあれば,2つの間の理想的な中間点になるだろう。これがJavaで実行可能なことは,すでにpojosrプロジェクトで実証されている。恐らくはこれが,すべての中で最も優れたソリューションだろう。
InfoQでは再出発したJigsawプロジェクトを間近にフォローして,その進捗を報告したいと考えている。