Java Gold モジュールシステム完全攻略|module-info.javaの書き方から–add-exportsまで徹底解説

ava Gold対策 モジュールシステムの仕組みとmodule-info.javaの書き方解説図
目次

1. モジュールシステム(Project Jigsaw)とは?

Java 9から導入された「モジュールシステム」。

一言でいうと、**「パッケージをさらにグループ化し、外部への公開範囲を厳格に制御する仕組み」**です。

従来のJavaでは、publicであればどこからでもアクセスできてしまいましたが、モジュールシステムによって「パッケージ単位で鍵をかける」ことが可能になりました。

【例題①:基礎中の基礎】

まずは、基本中の基本である「ファイル名」から確認しましょう。

Q:モジュール定義ファイルの名前として正しいものはどれですか?

  1. module.java
  2. module-info.java
  3. module_info.class
  4. package-info.java

正解:2

モジュール定義ファイルは、ソースルート直下に必ず module-info.java という名前で作成する必要があります。アンダースコアではなく「ハイフン」である点に注意!


2. module-info.javaの5つの基本指令(Directives)

試験で最も狙われるのが、この設定ファイルの書き方です。以下の5つは暗記必須です。

指令 (Directive)役割
requires依存する他のモジュールを指定する(インポート)
exports指定したパッケージを外部に公開する
opens実行時に「リフレクション」を許可する
provides…withサービス提供(インターフェースの実装)を宣言する
usesサービスを利用することを宣言する

【例題②:exportsとrequiresの違い】

Q:特定のパッケージを外部モジュールに対して公開し、利用可能にするキーワードはどれですか?

  1. requires
  2. exports
  3. opens
  4. to

正解:2

exports は自分のパッケージを外部に「公開」します。逆に、外部モジュールを利用(インポート)する場合は requires を使います。


3. 試験最頻出!「推移的依存(requires transitive)」

AモジュールがBを必要とし、BがCを必要としている場合、AからCを直接見れるようにするのが「推移的依存」です。

【例題③:依存の引き継ぎ】

Q:『推移的依存』を実現するために使用する正しい構文はどれですか?

  1. requires transitive モジュール名;
  2. exports transitive パッケージ名;
  3. opens transitive パッケージ名;
  4. public requires モジュール名;

正解:1

requires transitive を使うと、自モジュールを利用する他のモジュールに対しても、その依存関係を自動的に引き継がせることができます。


4. カプセル化を解除する「opens」

通常、非公開のメンバーにはリフレクションでもアクセスできませんが、それを許可するのが opens です。

【例題④:リフレクション対策】

Q:実行時にのみ、リフレクションによる非公開メンバーへのアクセスを許可する設定はどれですか?

  1. exports
  2. opens
  3. requires
  4. provides

正解:2

opens は、カプセル化を「開く」役割を持ちます。試験では「JSONライブラリがリフレクションを使うためにopensが必要」といった文脈で出ることがあります。

【例題⑤:公開先の限定】

Q:exportsキーワードで公開先を特定のモジュールだけに限定したい場合、どの構文を使用しますか?

  1. exports パッケージ名 limited モジュール名;
  2. exports パッケージ名 to モジュール名;
  3. exports パッケージ名 for モジュール名;

正解:2

exports ... to ... の形式で、特定の相手にだけ公開を許可します。これを「修飾されたエクスポート」と呼びます。


5. 自動モジュールと無名モジュール(移行期の仕組み)

「モジュール化されていない古いJARファイルをどう扱うか」は得点源です。

【例題⑥:自動モジュール】

Q:module-info.classを持たないJARを『モジュールパス』に配置した際、どのようなモジュールとして扱われますか?

  1. 名前付きモジュール
  2. 無名モジュール
  3. 自動モジュール

正解:3

モジュールパス(–module-path)に置くと 「自動モジュール」 になり、ファイル名からモジュール名が自動生成されます。

【例題⑦:無名モジュール】

Q:クラスパス上に配置されたすべてのクラスが属するモジュールを何と呼びますか?

  1. 無名モジュール
  2. 自動モジュール
  3. 基本モジュール

正解:1

従来の「クラスパス(–class-path)」に置かれたものは、すべて 「無名モジュール」 扱いになります。


6. 強力なコマンドラインツール(jdeps / jlink)

エンジニアなら知っておきたい、解析と配布のためのツールです。

【例題⑧:依存関係の解析】

Q:モジュールの依存関係を解析するために使用するコマンドはどれですか?

  1. jlink
  2. jdeps
  3. jmod

正解:2

jdeps (Java Dependency Analysis Tool) は、どのモジュールに依存しているかを静的に解析してくれます。

【例題⑨:カスタムJREの作成】

Q:必要なモジュールだけを組み合わせ、軽量なカスタム・ランタイムイメージを作成するツールはどれですか?

  1. jdeps
  2. jlink
  3. javac

正解:2

jlink を使うと、Java実行環境がないPCでも動く、最小限のサイズの実行イメージを書き出せます。


7. モジュール設定情報の調べ方

実際の開発や試験対策で「このモジュールには何が含まれているのか」「どのパッケージが公開されているのか」を確認したい場面があります。そのときに使うのが以下のコマンドです。

java –list-modules:利用可能なモジュール一覧を確認する

java --list-modules

JDKに含まれているすべてのモジュールの一覧が表示されます。java.basejava.sqlなど、どんなモジュールが存在するかを確認できます。

java –describe-module:特定モジュールの詳細を確認する

java --describe-module java.sql

指定したモジュールのrequires・exports・usesなどの設定内容をすべて表示します。「このモジュールは何に依存していて、何を公開しているか」を確認したいときに使います。

出力例:

java.sql@17
exports java.sql
exports javax.sql
requires java.base mandated
requires java.logging transitive
requires java.transaction.xa transitive
uses java.sql.Driver

この出力から「java.sqlはjava.baseを必須依存として持ち、java.loggingとjava.transaction.xaを推移的依存として持つ」ことがわかります。

jdeps –module-path:モジュールパスを指定して依存を解析する

jdeps --module-path mods -m myapp

自作モジュールの依存関係を解析するときに使います。--module-pathでモジュールの場所を指定し、-mで解析対象のモジュール名を指定します。

【例題⑩-補足:モジュール情報の確認】

Q:特定のモジュールのexports・requires・usesなどの設定内容を確認するためのコマンドはどれですか?

A. java --list-modules モジュール名
B. java --describe-module モジュール名
C. jdeps --describe モジュール名
D. jlink --info モジュール名

解説を見る

正解:B

--list-modulesは一覧表示のみで詳細は出ません。--describe-moduleを使うと指定モジュールのrequires・exports・usesなどの詳細設定をすべて確認できます。試験では「どのコマンドで何がわかるか」の使い分けが問われます。

8. モジュール境界を一時的に解除する:–add-modulesと–add-exports

モジュールシステムの厳格なカプセル化は便利な反面、「既存のライブラリが内部APIを使っていて動かない」「テスト時だけ非公開パッケージにアクセスしたい」という場面で困ることがあります。そのときに使うのが–add-modulesと–add-exportsです。

–add-modules:モジュールを明示的に追加する

java --add-modules java.xml.bind -jar myapp.jar

通常はmodule-info.javaのrequiresで依存を宣言しますが、module-info.javaを変更せずにモジュールを追加したい場合にコマンドライン引数で指定します。移行期に古いコードを動かすときなどに使われます。

複数指定する場合はカンマ区切りで指定します。

java --add-modules java.xml.bind,java.activation -jar myapp.jar

–add-exports:非公開パッケージへのアクセスを許可する

java --add-exports java.base/sun.security.x509=ALL-UNNAMED -jar myapp.jar

書き方は「モジュール名/パッケージ名=アクセスを許可するモジュール名」の形式です。

  • java.base/sun.security.x509:公開を許可するモジュールとパッケージ
  • ALL-UNNAMED:無名モジュール(クラスパス上のコード)すべてに許可する特殊キーワード

特定のモジュールだけに許可する場合はALL-UNNAMEDの代わりにモジュール名を指定します。

java --add-exports java.base/sun.security.x509=com.example.mymodule -jar myapp.jar

–add-opens:リフレクションによるアクセスを許可する

java --add-opens java.base/java.lang=ALL-UNNAMED -jar myapp.jar

–add-exportsはコンパイル時・実行時のアクセスを許可しますが、–add-opensはリフレクションによるアクセスも含めて許可します。module-info.javaのopensをコマンドラインから動的に指定するイメージです。

オプション用途対応するmodule-info.javaの指令
–add-modulesモジュールを明示的に追加するrequires
–add-exports非公開パッケージへのアクセスを許可するexports … to …
–add-opensリフレクションによるアクセスも含めて許可するopens … to …

【例題:–add-exportsの使い方】

Q:モジュールcom.example.app(無名モジュール上のコード)から、java.baseモジュールの非公開パッケージsun.utilにアクセスしたい場合、正しいコマンドライン引数はどれですか?

A. --add-exports sun.util=java.base/ALL-UNNAMED
B. --add-exports java.base/sun.util=ALL-UNNAMED
C. --add-modules java.base/sun.util
D. --add-opens sun.util/java.base=ALL-UNNAMED

解説を見る

正解:B

–add-exportsの書き方は「公開元モジュール名/パッケージ名=アクセス許可するモジュール名」の順番です。順番を逆に覚えないよう注意。無名モジュール(クラスパス上のコード)すべてに許可する場合はALL-UNNAMEDを使います。

【例題:–add-modulesと–add-exportsの違い】

Q:次の説明のうち正しいものはどれですか?

A. –add-modulesはパッケージの公開範囲を変更する
B. –add-exportsはモジュールをモジュールグラフに追加する
C. –add-modulesはmodule-info.javaを変更せずにモジュールを追加でき、–add-exportsは非公開パッケージへのアクセスを許可する
D. –add-modu

9. 高度な設定:サービス・ローダ

最後は少し難しい、インターフェースと実装の分離について。

【例題⑩:サービスの利用】

Q:モジュールが利用するサービス(インターフェース)を指定するキーワードはどれですか?

  1. provides
  2. uses
  3. with

正解:2

uses は利用側(ServiceLoaderなどを使う側)、provides ... with ... は実装を提供する側が使用します。


まとめ:モジュールシステム攻略のコツ

モジュールシステムは、一見難解ですが、module-info.javaの構文ルールさえ覚えてしまえば、Gold試験では確実に4〜5問は取れるボーナス分野です。

  1. requires/exports の向きを逆に覚えない。
  2. transitive の連鎖を理解する。
  3. jdeps/jlink の役割を混同しない。

この3点を意識して、黒本の問題を解き直してみてください。応援しています!

理解したら、問題で確認

Java Gold SE17のコード読解問題に挑戦する

この記事で学んだ内容を、Java Gold SE17向けの問題演習アプリで復習できます。 カテゴリ別問題と60問の模擬試験を、登録不要で利用できます。

Java Gold問題を解く →
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

tibiyaのアバター tibiya ITエンジニア

文系卒エンジニア(8年目)
Java / JavaScript / C# を中心に業務システム開発を経験。
Java資格・IT就活・文系エンジニアの実体験を発信しています。

コメント

コメントする

目次