JSR 294: Improved Modularity Support in the Java Programming Language

次期JavaプラットフォームであるJava SE 7ではモジュラリティの強化として2つの新しいAPIが追加される予定となっている。ひとつは本連載第12回でも紹介した「JSR 277: Java Module System」。そしてもうひとつが「JSR 294: Improved Modularity Support in the Java Programming Language」である。

現在、Javaではパッケージシステムによってプログラムのモジュール化を行うことができるようになっているが、JSR 294はそれをさらに強化するために"スーパーパッケージ"という概念を導入しようというものだ。スーパーパッケージとは具体的に次のようなものだと紹介されている。

  • パッケージや他のスーパーパッケージとそのタイプの集合
  • 明示的に"Export"されたメンバのみ外部からアクセスできる
  • "Export"されていないメンバは、同じスーパーパッケージ内の他のメンバからのみアクセスできる
  • Javaソースファイルによって定義し、Javaコンパイラによってコンパイルできる

これによって、あるパッケージを公開するか隠蔽するかを、パッケージごとに制御することが可能になる。このAPIについての概要は昨年5月に行われたJavaOneのレポート記事でも紹介しているが、現在正式にEarly Draftが公開されているので、今回はその中身をチェックしてみようと思う。

スーパーパッケージの定義

スーパーパッケージは、メンバとしてパッケージとスーパーパッケージを持つことができる。スーパーパッケージは、superpackageキーワードとmemberキーワードを用いてリスト1のように定義する。この例の場合、FooのメンバはHogeとBarである。したがってHogeとBarはFooの中で有効となっている。

リスト1

superpackage Foo {
             member package Hoge;
             member superpackage Bar;
}

BarはFooのメンバであるスーパーパッケージなのでリスト2のように定義する。PiyoはBarのメンバだが、この例のようにexport宣言することで外部にも公開される。この2つの例の場合、FooからBarの公開メンバであるPiyoにアクセスすることも可能となる。

リスト2

superpackage Bar menmer Foo {
             member package Piyo;
             export package Piyo;
}

さらに、もしBarが公開メンバとしてスーパーパッケージBazを含む場合、BazもFooからアクセスすることが可能となる。

リスト3

superpackage Bar menmer Foo {
             member package Piyo;
             member superpackage Baz;

             export package Piyo;
             export superpackage Baz;
}

JVM仕様の変更

スーパーパッケージの定義ファイルは「super-package.java」という名前で生成する。たとえばcom.fooという名前のスーパーパッケージならば、定義ファイルはcom/foo/super-package.javaとして作成しなければならないとのことだ。

これをコンパイルすると「com/foo/super-package.class」という名前のクラスファイルが生成される。そのフォーマットは新たに追加されるスーパークラスのためのクラスファイル仕様によって決められる。このクラスファイルにはスーパーパッケージ名、自身をメンバとするスーパーパッケージ名、メンバのパッケージ名、exportするパッケージまたはクラス名、スーパーパッケージのアノテーションといった情報が記載される。

また、通常のJavaプログラムのためのクラスファイル仕様も修正され、スーパーパッケージのための属性が追加される。その他、スーパーパッケージによってimportの仕組みが従来とは変わってくるため、それに伴ってクラスローディングの手順にも変更が加わることになる。

リフレクションAPIの変更

Javaでは、リフレクションAPIによってJavaクラスからフィールドやメソッドなどの情報を取得することができる。このリフレクションAPIに、スーパーパッケージの情報を扱うためのクラスやメソッドなどが追加される。現時点では以下のものが候補に上がっている。

  • java.lang.reflect.Superpackageクラス
  • java.lang.SuperpackageFormatErrorクラス
  • java.lang.Class.getSuperpackage()メソッド
  • java.lang.ClassLoader.defineSuperpackage(java.lang.String, byte[], int, int)メソッド
  • java.lang.ClassLoader.findSuperpackage(java.lang.String)メソッド
  • java.lang.annotation.ElementType.SUPERPACKAGEフィールド

その他の検討事項

上記の変更点に加え、エキスパートグループで今後検討していくべき項目として次のような内容が挙げられている。

  • 動的に生成/ロードされたクラスの、スーパーパッケージへの所属のさせ方
  • 新しく追加される予約語が本当に適切であるかどうか
  • 「スーパーパッケージ」以外の適切な呼び方はないか(たとえば「モジュール」など)
  • Exportのための構文について
  • JVM仕様に追加される新しい属性について

また、JSR 294はJSR 277と密接な関係にあるため、両仕様で矛盾が生じないようにすり合わせていくことも重要となる。