できない.dev

Java「package does not exist」が javac で出る原因と直し方

package does not exist は、依存 jar を -cp に渡すか、-sourcepath で自作パッケージも一緒にコンパイルすれば直る。
コンパイル時のクラスパスに無いと出る。

公開: 更新:

症状できない · exit 1
javac -d out src/com/example/B.java
…
src/com/example/B.java:3: error: package com.other does not exist
import com.other.Missing;
                ^
src/com/example/B.java:7: error: cannot find symbol
解決後できた · exit 0
javac -cp out3 -d out3 src/com/example/B.java

2026-10-15 に eclipse-temurin:21-jdk(Java 21.0.12.1) で実際に打って取った出力。検証環境の詳細

要約

package ... does not exist は、コンパイル時のクラスパス上にそのパッケージが見つからないという意味である。
実行時のエラーではないので、-cp と -sourcepath の指定を見直せば解決する。

src/com/example/B.java:2: error: package com.other does not exist
import com.other.Missing;
                ^

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

実行例

eclipse-temurin:21-jdk で上記の手順を動かすと、B.java だけをコンパイルした場合は package com.other does not exist に続いて cannot find symbol が出て、2 件のエラーで終了コード 1 になった。
参照先のソースを一緒に渡す、-sourcepath src を付ける、先に出力した out3 を -cp に渡す、のいずれでもコンパイルは終了コード 0 で通った。

$ javac -d out src/com/example/B.java
src/com/example/B.java:3: error: package com.other does not exist
import com.other.Missing;
                ^
src/com/example/B.java:7: error: cannot find symbol
        System.out.println(Missing.hello());
                           ^
  symbol:   variable Missing
  location: class B
2 errors
$ echo $?
1
$ javac -d out src/com/other/Missing.java src/com/example/B.java
$ echo $?
0
$ java -cp out com.example.B
hello from com.other
$ javac -sourcepath src -d out2 src/com/example/B.java
$ echo $?
0
$ javac -d out3 src/com/other/Missing.java
$ javac -cp out3 -d out3 src/com/example/B.java
$ echo $?
0
$ java -cp out3 com.example.B
hello from com.other

— 2026-10-15 時点の出力

検証環境Java 21.0.12.1 / 2026-10-15 検証
検証日
実行環境
eclipse-temurin:21-jdk Ubuntu 26.04.1 LTS
バージョン
  • Java 21.0.12.1

この記事の「実行例」は、上記の環境で実際にコマンドを実行して得られた出力をそのまま掲載しています。 再現手順はリポジトリの検証スクリプトとして管理し、定期的に再実行して出力を更新しています。

解決策

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 コマンドの公式ドキュメント(新しいタブで開く)にまとまっている。

よくある原因

  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 が続くのは普通の連鎖で、後者だけを追っても解決しない。
先頭のエラーから潰す。