こんにちは, Shinoryoです.
今回はJavaのモジュールシステムに関してまとめてみた結果を書き連ねていこうと思います.
目次[非表示]
モジュールシステム
- モジュールシステム(module system):複数のパッケージをモジュールという単位でまとめることができるようになったもの.
目的
- パッケージ単位の情報隠蔽を実現する.
- アプリケーションモジュールとJDKのモジュールのリンクを容易に構築する.
モジュールの作成手順
- モジュール用のディレクトリを作成する.
- そのディレクトリに, module-info.javaというファイルを作る.
- 例えば次のようにコンパイルする:
$ javac -d mods/moduleA src/moduleA/com/example/module-info.java src/moduleA/com/example/Main.java
mods/moduleA
:クラスファイルの出力先ディレクトリsrc/moduleA/module-info.java
:コンパイルするファイルのパス1src/moduleA/com/example/a/Main.java
:コンパイルするファイルのパス2
module-info.javaの記述内容
module-info.javaには次の2点を記述する. これにより, このモジュールがどのようなモジュールなのかを設定することができる.
- どのパッケージを公開するか(exports)
- 他のどのモジュールを使うのか(requires)
module moduleA { exports package1; // 公開するパッケージ名を記述 exports package2; // 公開するパッケージが複数ある場合は, その個数だけexportsを記述する requires module1; // 利用するモジュール名を記述 requires module2; // 利用するモジュールが複数ある場合は, その個数だけrequiresを記述する }
モジュールの実行手順
例えば次のように実行する:
$ java --module-path mods -m moduleA/com.example.Main
mods
:モジュールが存在するディレクトリmoduleA
:モジュール名com.example.Main
:実行したいクラスの完全修飾クラス名
モジュール間の依存関係
モジュールグラフ
- モジュールグラフ(module graph):モジュール間の依存関係を表した図.
- モジュールAがモジュールBに依存する場合, モジュールAからモジュールBに向かって矢印が引かれる.
図1 モジュールグラフの例.
推移的な依存関係
- 推移的な依存関係(transitive dependencies):自分が必要とするモジュールを, 自分を必要とするモジュールにも利用させること.
図1の依存関係において, module-info.javaには次のように記述される.
moduleAのmodule-info.java
module moduleA { requires moduleB; }
moduleBのmodule-info.java
module moduleB { requires moduleC; }
この場合だと, moduleAはmoduleCに属するクラスを利用することができない. moduleAがmoduleBを飛び越してmoduleCに属するクラスを利用するには, moduleBもmodule-info.javaを次のように変更する.
module moduleB { requires moduleC transitive; }
相互依存によるコンパイルエラー
- 相互依存:複数のモジュールが相互に利用しあっている状況.
- コンパイラーが延々とそれぞれの設定ファイルを確認し続けることになるため, コンパイルエラーが発生する.
モジュールに関するコマンド
モジュールの情報を確認する
モジュールの情報を確認する方法は, 次の2つがある.
- javaコマンドの--describe-moduleオプションを使う.
$ java --module-path mods --descrive-module moduleA
- jmodコマンドのdescribeモードを使う.
$ jmod create --class-path mods/moduleA moduleA.jmod $ jmod describe moduleA.mod
- JMODファイル形式:クラスファイルなどが1つのモジュールとしてまとまったファイル形式. ネイティブコードを含めることができるのが, JARファイル形式との大きな違いである.
モジュールの依存関係を確認する
モジュールの依存関係を確認する方法は, 次の2つがある.
- javaコマンドの--show-module-resolutionオプションを使う.
$ java --module-path mods --show-module-resolution -m moduleA/com.example.a.Main
- jdepsコマンドを使う.
$ jdeps mods/moduleA
非公開パッケージを一時的に利用する
- javacコマンドの--add-exportsオプション:module-info.javaでexports宣言がされていないパッケージを, 一時的に利用してコンパイルするためのオプション.
$ javac -d mods/moduleA --module-path mods --add-exports moduleB/com.example.b=moduleA src/moduleA/module-info.java src/moduleA/com/example/a/Main.java
- 「--add-exports (対象のモジュール)/(公開するパッケージ)=(利用するモジュール)」の形式で記述する.
- 緊急避難的に利用すべきものである. 乱用すると, パッケージの公開設定の制御が失われてしまう.
java.baseモジュール
- java.baseモジュール:java.langパッケージ, java.utilパッケージ, java.ioパッケージなど, どのようなプログラムであっても使うであろうパッケージをまとめたもの.
- 明示的に
requires
で宣言しなくても, 自動的に読み込まれる. - 明示的に
requires
で宣言しなかった場合, モジュールの情報の出力には代わりに次の行が含まれる:
- 明示的に
module moduleA { // 略 requires java.base mandated // 略 }
参考文献
- 志賀澄人. 徹底攻略 Java SE 11 Silver問題集 : [1Z0-815]対応. 東京, インプレス, 2019, p.371–392, 397, 412, 452, 453, 468, ISBN4-295-00762-5.
- Deitel, Paul. “Java 9 Modulesの理解”. Oracle. https://www.oracle.com/jp/corporate/features/understanding-java-9-modules.html, (参照 2023-11-24)
Java 9 Modulesの理解 | Oracle 日本
内容と使用方法
- tyab. “Java JMODファイルとは, JARファイルとの違い. ”. tyablog.net. 2020-04-05. https://tyablog.net/2020/04/05/java-how-different-jmod-and-jar/, (参照 2023-11-24).
Java JMODファイルとは, JARファイルとの違い. | tyablog.net
この記事では, JPMS (Java Platform Module System) が導入されてから追加された, 新しいファイル形式, JMODファイルについて解説します. また, 元々あるJARファイルとの違いについても触れていきます. 最後に, JMODファイルの作成方法を通して, JMODファイルが, 実際どういうものなのか, 更に理解を深めたいと思います. JMODファイルとは JMODファイルは,
0 件のコメント:
コメントを投稿 (Please feel free to ask me about your questions! You can use Japanese or English in the comments.)