質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.31%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

Q&A

1回答

929閲覧

java --module-path[;...] と --add-modules[,...] の違いについて

k.fujisawa

総合スコア42

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

0グッド

0クリップ

投稿2024/03/11 18:13

・自動モジュールから名前付きモジュールを参照
・無名モジュールから自動モジュール、名前付きモジュールを参照

上記は--add-modulesで指定すれば参照できます。
--add-modulesで指定せずに--module-pathで指定した場合、参照できません。

--add-modulesと--module-pathにはどのような違いがあるのでしょうか?
それぞれの動作について教えていただきたいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

k.fujisawa

2024/03/16 15:18 編集

<module-info.java> module namedA {} <module-info.java> module namedB {} <module-info.java> module namedC {} <packageA.java> package packageA; public class packageA { public static void main(String[] args) { System.out.println(packageA.class); System.out.println(packageB.packageB.class); System.out.println(packageC.packageC.class); } } <packageB.java> package packageB; public class packageB { public static void main(String[] args) { System.out.println(packageA.packageA.class); System.out.println(packageB.class); System.out.println(packageC.packageC.class); } } <packageC.java> package packageC; public class packageC { public static void main(String[] args) { System.out.println(packageA.packageA.class); System.out.println(packageB.packageB.class); System.out.println(packageC.class); } } <コンパイル・jarファイル化> cd /temporary & javac -encoding utf-8 ./tempA/module-info.java ./tempA/packageA/packageA.java ./tempB/packageB/packageB.java ./tempC/packageC/packageC.java & javac -encoding utf-8 ./tempB/module-info.java ./tempA/packageA/packageA.java ./tempB/packageB/packageB.java ./tempC/packageC/packageC.java & javac -encoding utf-8 ./tempC/module-info.java ./tempA/packageA/packageA.java ./tempB/packageB/packageB.java ./tempC/packageC/packageC.java & jar -cf ./tempA/automaticA.jar -C ./tempA ./packageA/packageA.class & jar -cf ./tempB/automaticB.jar -C ./tempB ./packageB/packageB.class & jar -cf ./tempC/automaticC.jar -C ./tempC ./packageC/packageC.class <ディレクトリ構造> cd /temporary & tree /f C:. │ java │ javac ├─tempA ││ automaticA.jar ││ module-info.class ││ module-info.java │└─packageA │ packageA.class │ packageA.java ├─tempB ││ automaticB.jar ││ module-info.class ││ module-info.java │└─packageB │ packageB.class │ packageB.java └─tempC ││ automaticC.jar ││ module-info.class ││ module-info.java │└─packageC │ packageC.class │ packageC.java ①--add-modules有)自動モジュールAから無名モジュールB、名前付きモジュールCを参照 cd /temporary & java --show-module-resolution -cp ./tempB -p ./tempA/automaticA.jar;./tempC --add-modules namedC --add-exports namedC/packageC=automaticA -m automaticA/packageA.packageA root automaticA file:///C:/temporary/./tempA/automaticA.jar automatic root namedC file:///C:/temporary/./tempC/ class packageA.packageA class packageB.packageB class packageC.packageC ②--add-modules無)自動モジュールAから無名モジュールB、名前付きモジュールCを参照 cd /temporary & java --show-module-resolution -cp ./tempB -p ./tempA/automaticA.jar;./tempC --add-exports namedC/packageC=automaticA -m automaticA/packageA.packageA root automaticA file:///C:/temporary/./tempA/automaticA.jar automatic class packageA.packageA class packageB.packageB Exception in thread "main" java.lang.NoClassDefFoundError: packageC/packageC ③--add-modules有)自動モジュールAから自動モジュールB、Cを参照 cd /temporary & java --show-module-resolution -p ./tempA/automaticA.jar;./tempB/automaticB.jar;./tempC/automaticC.jar; --add-modules automaticB,automaticC -m automaticA/packageA.packageA root automaticA file:///C:/temporary/./tempA/automaticA.jar automatic root automaticB file:///C:/temporary/./tempB/automaticB.jar automatic root automaticC file:///C:/temporary/./tempC/automaticC.jar automatic class packageA.packageA class packageB.packageB class packageC.packageC ④--add-modules無)自動モジュールAから自動モジュールB、Cを参照 cd /temporary & java --show-module-resolution -p ./tempA/automaticA.jar;./tempB/automaticB.jar;./tempC/automaticC.jar; -m automaticA/packageA.packageA root automaticA file:///C:/temporary/./tempA/automaticA.jar automatic automaticA requires automaticB file:///C:/temporary/./tempB/automaticB.jar automatic automaticA requires automaticC file:///C:/temporary/./tempC/automaticC.jar automatic class packageA.packageA class packageB.packageB class packageC.packageC ⑤--add-modules有)名前付きモジュールAから自動モジュールB、Cを参照 cd /temporary & java --show-module-resolution -p ./tempA;./tempB/automaticB.jar;./tempC/automaticC.jar --add-modules automaticB,automaticC --add-reads namedA=automaticB,automaticC -m namedA/packageA.packageA root automaticB file:///C:/temporary/./tempB/automaticB.jar automatic root namedA file:///C:/temporary/./tempA/ root automaticC file:///C:/temporary/./tempC/automaticC.jar automatic class packageA.packageA class packageB.packageB class packageC.packageC ⑥--add-modules無)名前付きモジュールAから自動モジュールB、Cを参照 cd /temporary & java --show-module-resolution -p ./tempA;./tempB/automaticB.jar;./tempC/automaticC.jar --add-reads namedA=automaticB,automaticC -m namedA/packageA.packageA root namedA file:///C:/temporary/./tempA/ class packageA.packageA Exception in thread "main" java.lang.NoClassDefFoundError: packageB/packageB ⑦--add-modules有)名前付きモジュールAから名前付きモジュールB、Cを参照 cd /temporary & java --show-module-resolution -p ./tempA;./tempB;./tempC --add-modules namedB,namedC --add-reads namedA=namedB,namedC --add-exports namedB/packageB=namedA --add-exports namedC/packageC=namedA -m namedA/packageA.packageA root namedC file:///C:/temporary/./tempC/ root namedB file:///C:/temporary/./tempB/ root namedA file:///C:/temporary/./tempA/ class packageA.packageA class packageB.packageB class packageC.packageC ⑧--add-modules無)名前付きモジュールAから名前付きモジュールB、Cを参照 cd /temporary & java --show-module-resolution -p ./tempA;./tempB;./tempC --add-reads namedA=namedB,namedC --add-exports namedB/packageB=namedA --add-exports namedC/packageC=namedA -m namedA/packageA.packageA root namedA file:///C:/temporary/./tempA/ class packageA.packageA Exception in thread "main" java.lang.NoClassDefFoundError: packageB/packageB ⑨--add-modules有)無名モジュールAから自動モジュールB、名前付きモジュールCを参照 cd /temporary & java --show-module-resolution -cp ./tempA -p ./tempB/automaticB.jar;./tempC --add-modules automaticB,namedC --add-exports namedC/packageC=ALL-UNNAMED packageA.packageA root namedC file:///C:/temporary/./tempC/ root automaticB file:///C:/temporary/./tempB/automaticB.jar automatic class packageA.packageA class packageB.packageB class packageC.packageC ⑩--add-modules無)無名モジュールAから自動モジュールB、名前付きモジュールCを参照 cd /temporary & java --show-module-resolution -cp ./tempA -p ./tempB/automaticB.jar;./tempC --add-exports namedC/packageC=ALL-UNNAMED packageA.packageA class packageA.packageA Exception in thread "main" java.lang.NoClassDefFoundError: packageB/packageB
k.fujisawa

2024/03/27 12:24 編集

<module-info.java> module namedA {} <packageA.java> package packageA; public class packageA { public static void main(String[] args) throws Throwable { System.out.println(Class.forName("packageB.packageB")); } } <packageB.java> package packageB; public class packageB { public static void main(String[] args) { System.out.println(packageC.packageC.class); } } <packageC.java> package packageC; public class packageC {} <コンパイル・jarファイル作成> cd /temporary & javac -encoding utf-8 ./tempA/module-info.java ./tempA/packageA/packageA.java ./tempB/packageB/packageB.java ./tempC/packageC/packageC.java & jar -cf ./tempB/automaticB.jar -C ./tempB ./packageB/packageB.class & jar -cf ./tempC/automaticC.jar -C ./tempC ./packageC/packageC.class <ディレクトリ構造> cd /temporary & tree /f C:. │ java │ javac ├─tempA ││ module-info.class ││ module-info.java │└─packageA │ packageA.class │ packageA.java ├─tempB ││ automaticB.jar │└─packageB │ packageB.class │ packageB.java └─tempC ││ automaticC.jar │└─packageC │ packageC.class │ packageC.java ⑪--add-modules有 cd /temporary & java --show-module-resolution -p ./tempA;./tempB;./tempC --add-modules automaticB -m namedA/packageA.packageA root automaticB file:///C:/temporary/./tempB/automaticB.jar automatic root namedA file:///C:/temporary/./tempA/ automaticB requires automaticC file:///C:/temporary/./tempC/automaticC.jar automatic class packageB.packageB ⑫--add-modules無 cd /temporary & java --show-module-resolution -p ./tempA;./tempB;./tempC -m namedA/packageA.packageA root namedA file:///C:/temporary/./tempA/ Exception in thread "main" java.lang.ClassNotFoundException: packageB.packageB ⑬--add-modules無 -cp有 cd /temporary & java --show-module-resolution -cp ./tempB -p ./tempA;./tempB;./tempC -m namedA/packageA.packageA root namedA file:///C:/temporary/./tempA/ class packageB.packageB
guest

回答1

0

—module-pathはmodule-info.classを格納するフォルダあるいはjarファイルへのルートパスを指定するコマンドです

javac module-info.java source.java —module-path Directory;Directory

モジュールは依存関係に従ってコンパイルされる必要があり、依存先として指定されるディレクトリにはmodule-info.classが予め存在していなければなりません
module-info.javaをコンパイルする場合はこちらを用います

—add-modulesは参照するモジュール名を指定するコマンドです
—module-pathで指定されたディレクトリ上に存在するモジュール名を参照します

javac Source.java Source.java —add-modules ModuleName,ModuleName —module-path Directory;Directory

インポートされたパッケージのクラスをモジュールから参照する場合にこちらを用います
クラスパスの代わりにモジュールを参照することで、ソースファイル上で利用されるパッケージが指定のモジュールから公開された状態にあるかを通知します
非公開のパッケージをインポートしている場合はエラーが明示されます

投稿2024/03/12 17:38

編集2024/03/13 02:07
TokoToko123

総合スコア25

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

k.fujisawa

2024/03/12 23:02

自動モジュールから名前付きモジュールを参照する場合は、--add-modulesが必要。 名前付きモジュールから自動モジュールを参照する場合は、--add-modulesが不要。 なぜ、後者は—module-pathの指定だけで参照できるのでしょうか?
TokoToko123

2024/03/13 02:05 編集

module-info.classを持たないフォルダあるいはjarファイルをモジュールとして利用する場合、そのディレクトリには暗黙的にディレクトリ名と同じモジュール名が付与されます モジュールによるパッケージの公開及び他のモジュールへの依存は、module-infoファイルで定義します ここで指定可能な依存モジュールの種類は次の通りです •固有名を持つモジュール •ディレクトリ名が適用されるモジュール モジュールの依存関係は、ルートパスに属するmodule-info.classの有無で判定します このクラスファイルが確認されない状況ではディレクトリ名での命名による解決を図ります 一連の判定は—module-pathにより実行されます このソースとなるのがmodule-infoファイルです module-infoファイルを持たないディレクトリから他のモジュールを参照する際は、参照元のソースが存在しない状態となるため、依存先となるモジュールの名前をコンパイラへ明示します これを担うオプションが—add-modulesです
k.fujisawa

2024/03/13 08:51 編集

<①ソースコード> package packageA; public class packageA { public static void main(String[] args) { System.out.println("sysoutA"); } } <②コンパイル> C:\>javac -encoding utf-8 packageA/packageA.java <③jarファイル作成> C:\>jar -cf test.jar packageA/packageA.class <④実行> java -p ./ -m test/packageA.packageA <⑤実行結果> sysoutA >module-info.classを持たないフォルダあるいはjarファイルをモジュールとして利用する場合、 >そのディレクトリには暗黙的にディレクトリ名と同じモジュール名が付与されます ★どのようにしてmodule-info.classを持たないフォルダをモジュールとして利用できますか?  ※jarファイルをモジュールとして利用することはできました。 以下、実行の詳細になります。 すみませんが、ご確認お願いします。 <実行> C:\>java -p ./ -m packageA/packageA.packageA <結果> java.lang.module.FindException: Module packageA not found <ディレクトリ階層> c: ├─test.jar └─packageA   ├─packageA.java   └─packageA.class  
k.fujisawa

2024/03/14 13:50 編集

丁寧な回答ありがとうございます。ようやく少し整理できてきました。 以下の理解で問題ないですか?また、分からない点があります。ご確認お願いします。 <自動モジュールに関して> ・モジュールグラフ上の全モジュールをrequiresする。 ・モジュールグラフに自動モジュール(初期モジュールと異なる)、           無名モジュールは含まれる。 ・モジュールグラフに名前付きモジュールは含まれない。 ・--module-path : モジュールを参照するディレクトリを指定する。 ・--module : 初期モジュールを指定する。 ・--add-modules : 初期モジュールに加えて解決するルートモジュールを指定する。 ★自動モジュール起点のモジュールグラフに自動モジュール(ルートモジュールと異なる)、  無名モジュールは含まれて、名前付きモジュールが含まれないのはなぜでしょうか? ★無名モジュール起点のモジュールグラフに自動モジュール、名前付きモジュールが  含まれないのはなぜでしょうか?
TokoToko123

2024/03/14 12:16 編集

•フォルダ名をモジュール名とする方法について (訂正含む) まず、問題のコードについての対処方法は次のいずれかです ・Javaファイルの指定 Java packageA/packageA.java -p . •フォルダと同一名のjarファイルの作成 jar -cvf packageA.jar * フォルダと同名のjarファイルを持つことで、そのフォルダ名をモジュールの名前として扱えます jarファイルを使用する場合の—add-modulesを含めたコマンドの書式は以下です javac Source.java Source.java —add-modules Module(jar)Name,Module(jar)Name —module-path Directory;Directory >module-info.classを持たないフォルダ この表現が誤認を生む原因となったことをお詫び致します 仕様に正しく沿った解説ではないため以下の通りに訂正します > module-info.classを持たないjarファイルのルートフォルダ
TokoToko123

2024/03/14 14:20

関連コマンドについての基本的な理解に関しては、—add-moduleについて幾つか留意点があります ・—add-modulesはモジュールをモジュールグラフへ追加しません モジュールグラフはモジュールパスの指定時に構築済みです 無名モジュール(javaファイル)からの参照時に対象となる自動モジュール(jarファイル)を名前付きモジュール(module-info.class)へ切り替える場面で用います (例) java —module-path Directory;Directory —add-modules ModuleName(by module-info.class) Source.java •—add-modulesには全てのモジュールを明示する必要はありません 前述の用途に則った切り替え対象のモジュールのみを明示します 後半の二点については、具体的なコードをご提示頂ければより詳細な回答が可能かもしれません ただ、以上のようにmodule-info.classを用いないモジュールの仕様は、回答で示した運用例よりも複雑になります jarファイルをモジュールとして使用する際も、jarファイルそれ自体はモジュール定義を持たないディレクトリである点に注意が必要です 原則としては、module-info.classを用意することが望ましいと言えます
k.fujisawa

2024/03/16 16:04 編集

>—add-modulesはモジュールをモジュールグラフへ追加しません >モジュールグラフはモジュールパスの指定時に構築済みです "add-modulesはルートモジュールを追加する"であってますか? 以下、ソース等詳細は掲題の質問に追記しています。 ⑪--add-modules有 cd /temporary & java --show-module-resolution -p ./tempA;./tempB;./tempC --add-modules automaticB -m namedA/packageA.packageA root automaticB file:///C:/temporary/./tempB/automaticB.jar automatic root namedA file:///C:/temporary/./tempA/ automaticB requires automaticC file:///C:/temporary/./tempC/automaticC.jar automatic class packageB.packageB ⑫--add-modules無 cd /temporary & java --show-module-resolution -p ./tempA;./tempB;./tempC -m namedA/packageA.packageA root namedA file:///C:/temporary/./tempA/ Exception in thread "main" java.lang.ClassNotFoundException: packageB.packageB ⑪、⑫の実行結果から、 --add-modulesコマンドによってルートモジュールが追加される。 初期モジュールだけでなく、--add-modulesで指定したルートモジュール に対してもモジュール解決は実行される。 こちらの認識は正しいでしょうか?ご確認お願いします。
k.fujisawa

2024/03/17 02:34 編集

>module-infoファイルを持たないディレクトリから他のモジュールを参照する際は、 >参照元のソースが存在しない状態となるため、依存先となるモジュールの名前をコンパイラへ明示します >これを担うオプションが—add-modulesです おおよそ理解できたかなと思いますが、 違和感のあるパターンがあります。 ①②自動モジュールから名前付きモジュールを参照するとき、—add-modules必要 ⑤⑥requires無しの名前付きモジュールから自動モジュールを参照するとき、—add-modules必要 ⑦⑧requires無しの名前付きモジュールAから名前付きモジュールBを参照するとき、—add-modules必要 ⑨⑩無名モジュールから自動モジュール、名前付きモジュールを参照するとき、—add-modules必要 上記のパターンに関しては納得できたのですが、 下記のパターンはなぜ—add-modulesが不要になるのか。分かりません。 依存先となるモジュールの名前をコンパイラへ明示する必要はないのでしょうか? ご確認お願いします。 ③④自動モジュールAから自動モジュールBを参照するとき、—add-modules不要 ソース等詳細は掲題の質問に追記しています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.31%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問