Java の javac で「package does not exist」が解決できない
package ... does not exist はコンパイル時にクラスパス上でそのパッケージが見つからないという意味である。
依存 jar を -cp に渡すか、-sourcepath と -d を整えて自作パッケージを一緒にコンパイルすれば解決する。
公開:
要約
package ... does not exist は、コンパイル時のクラスパス上にそのパッケージが見つからないという意味である。
実行時のエラーではないので、-cp と -sourcepath の指定を見直せば解決する。
src/com/example/B.java:2: error: package com.other does not exist
import com.other.Missing;
^エラー行に出ている名前空間が「他人のライブラリ」なのか「自分の別パッケージ」なのかで対処が分かれる。
よくある原因
- 依存 jar を渡していない: 外部ライブラリの名前空間は、jar をクラスパスに載せて初めて存在する。
ビルドツールを使わずjavacを直接叩いたときに起きやすい。 - 自分の別パッケージがまだコンパイルされていない: 参照先の
.classが無ければ、同じメッセージが自作パッケージに対しても出る。 - 宣言とディレクトリがずれている:
package com.example;のファイルはcom/example/の下に置く必要がある。
ここがずれるとjavacは探索できない。 - 前回の出力先を渡していない:
-d outで分けて出したのに、次のコンパイルで-cp outを付けていないパターンである。
なお package ... does not exist の直後に cannot find symbol が続くのは普通の連鎖で、後者だけを追っても解決しない。
先頭のエラーから潰す。
解決策
1. 依存 jar をクラスパスへ渡す
javac -cp "libs/*" -d out src/com/example/B.java複数の jar を含むディレクトリはワイルドカードで指定できる。
区切り文字は Linux / macOS が :、Windows が ; である。
2. 自作パッケージを一緒にコンパイルする
javac -d out $(find src -name '*.java')一括で渡すのが確実である。
個別に渡したいなら -sourcepath src を付けて、参照先を javac に探させる。
3. ディレクトリ構成を宣言に合わせる
src/
com/
example/
App.java ← package com.example;4. 出力先を次のコンパイルへ引き継ぐ
javac -d out src/com/example/App.java
javac -cp out -d out src/com/example/C.java-d の出力先を -cp にも渡しておけば、既にコンパイル済みのクラスを再利用できる。
オプションの詳細は javac コマンドの公式ドキュメント(新しいタブで開く)にまとまっている。