今更ながら、今現在ではあまり必要ではないと思われる知識をUPDATEしたので念のためブログにまとめておこうと思います。
タイトルの通りですが、内容はJavaのソースファイルをコンパイルするときに使うコマンドであるjavacの「sourcepath」オプションの意味についてです。
javacコマンドのhelpに記載されている「sourcepath」オプションの説明は以下の通りです。
まあ、言っていることの意味はなんとなく分かるのですが、コンパイルするときに対象のソースファイルを引数で指定するため、このオプションに指定したソースファイルに何の意味があるのかよくわかりませんでした。
なので、実際に動作確認しながらこのオプションがどのように機能するかを確認したいと思います。サンプルとして、以下のようなフォルダ階層で2つのソースファイル(A.javaとB.java)を用意します。
A.javaのサンプルコードです。パッケージaに所属しています。
package a; import b.B; public class A { private B b; }
B.javaのサンプルコードです。パッケージbに所属しています。
package b; public class B { }
AクラスからBクラスをフィールド定義しているという以外は何も意味のないプログラムです。今回は「sourcepath」オプションの挙動を確認するためだけなので、処理は何も記載していません
それでは、A.javaを以下のコマンドでコンパイルしてみましょう。「-d」オプションは、コンパイルした際に出力されるclassファイルの出力先を指定するオプションです。今回は、classesフォルダを指定します。
C:\work\tmp>javac src\a\A.java -d classes
実行すると以下のエラーになりました。エラー内容としては、Aクラスで参照しているBクラスが見つけられないというエラーです。
javacコマンドは、コンパイル対象のJavaファイルを解析して、そのファイルで参照しているクラスを探します。今回は、AクラスでBクラスが参照されているので、javacコマンドはBクラスを探そうとしますが、見つけることができないためエラーとなってしまったようです。
これを解決するのが、「sourcepath」オプションです。以下のように「sourcepatah」オプションにsrcフォルダを指定して再度実行してみましょう。
C:\work\tmp>javac src\a\A.java -d classes -sourcepath src
上記の通り、何もエラーがないのでコンパイルは成功したということですね。このように、「sourcepath」オプション一つで結果が変わりました。なぜコンパイルできたのでしょうか。
javacコマンドは、指定されたJavaファイルをコンパイルする際に参照しているクラスを探すと前述しました。
今回のケースでは、Aクラスで参照しているBクラスを探します。この時に「sourcepath」オプションを指定しない場合は、デフォルトではカレントディレクトリが探す対象の起点(場所)となります。
今回javacコマンドを実行したのは、「C:\work\tmp」ですが、ここをクラスを探す起点とした場合に、Bクラスはパッケージ"b"であるため、b\B.javaというパスで参照できなければならないのですが、実際のファイルまでのパスは、src\b\B.javaであるため、javacコマンドはBクラスを探すことができません。そのため、コンパイルエラーになりました。
「sourcepath」オプションにsrcディレクトリを指定することで、srcディレクトリを起点とした場合には「b\B.java」でBクラスを探すことができるため、エラーにならずにコンパイルが成功したということです。
このような仕組みであるため、例えばカレントディレクトリをソースファイルの起点ディレクトリにすることで「sourcepath」オプションなしでコンパイルできるようになります。
普段はEclipseなどのIDEやMavenなどのビルドツールで管理しているので、javacの「sourcepath」オプションの意味を知らなかったのですが、原理として知っておくことはいいことだなと思いました。
今回はこの辺で失礼いたします。最後までお読みいただきありがとうございました。