導入
Java 9で導入された「Javaモジュールシステム(Project Jigsaw)」は、Javaプラットフォームの構造を大きく変革しました。従来のクラスパスによる管理は、ライブラリ間の依存関係が不明確になりがちで、巨大なアプリケーションでは「JAR地獄」と呼ばれる問題を引き起こしていました。モジュールシステムを理解することは、現代のJava開発における堅牢なアプリケーション設計と、不要なパッケージを排除した軽量な実行環境を作るために不可欠です。
基礎知識
モジュールとは、関連するパッケージやリソースをひとまとめにした新しい単位です。モジュールの定義は、ルートディレクトリに配置する「module-info.java」ファイルで行います。
ここで重要になるのが「カプセル化」です。モジュールは、明示的に公開(exports)したパッケージ以外は、他のモジュールからアクセスできません。また、リフレクションによるアクセスを許可するには「opens」キーワードを使用します。これにより、ライブラリの内部実装を外部から隠蔽し、安全性を高めることができます。
実装/解決策
モジュールを作成する際は、まずmodule-info.javaで依存関係と公開範囲を定義します。
1. exports: 指定したパッケージを他モジュールから利用可能にする(コンパイル時・実行時にアクセス可能)。
2. opens: 指定したパッケージをリフレクション経由で利用可能にする(主にフレームワーク用)。
3. requires: 必要な依存モジュールを宣言する。
サンプルプログラム
以下は、特定のパッケージを公開し、他のモジュールからの利用を許可する構成例です。
// module-info.java
// このモジュールを ‘com.example.service’ と定義します
module com.example.service {
// 他のモジュールからこのパッケージ内のクラスを利用可能にします
exports com.example.service.api;
// リフレクションで内部クラスにアクセスするフレームワーク等のために公開します
opens com.example.service.internal to com.example.framework;
// 必要な外部モジュールを宣言します
requires java.sql;
}
// com/example/service/api/Greeting.java
package com.example.service.api;
public class Greeting {
public void sayHello() {
System.out.println(“モジュール経由で呼び出されました”);
}
}
応用・注意点
現場でモジュールシステムを扱う際、最も注意すべきは「非公開APIへのアクセス」です。外部ライブラリが内部APIにリフレクションでアクセスしようとすると、IllegalAccessExceptionが発生することがあります。これを回避するために、開発環境(IDE)や起動オプションで `–add-opens` を指定することがありますが、これはあくまで「応急処置」です。基本的には、モジュール化されたライブラリのバージョンアップを行い、公式にサポートされているAPIを使用する設計を心がけてください。
また、既存の古いライブラリ(モジュール化されていないもの)を扱う場合は、それらが「自動モジュール」として扱われる点も理解しておくと、移行時のトラブルを未然に防ぐことができます。

コメント