できない.dev

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;
                ^

エラー行に出ている名前空間が「他人のライブラリ」なのか「自分の別パッケージ」なのかで対処が分かれる。

よくある原因

  1. 依存 jar を渡していない: 外部ライブラリの名前空間は、jar をクラスパスに載せて初めて存在する。
    ビルドツールを使わず javac を直接叩いたときに起きやすい。
  2. 自分の別パッケージがまだコンパイルされていない: 参照先の .class が無ければ、同じメッセージが自作パッケージに対しても出る。
  3. 宣言とディレクトリがずれている: package com.example; のファイルは com/example/ の下に置く必要がある。
    ここがずれると javac は探索できない。
  4. 前回の出力先を渡していない: -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 コマンドの公式ドキュメント(新しいタブで開く)にまとまっている。

この記事は役立ちましたか?