できない.dev

Java で「Could not find or load main class」が解決できない

java コマンドに渡すのはファイル名ではなく完全修飾クラス名で、.class が置かれたルートディレクトリを -cp で指す必要がある。
拡張子付きの指定とパッケージ名の省略が二大原因である。

公開: 更新:

実行例あり(2026-09-11 に実環境で検証)

要約

Error: Could not find or load main class ... は、JVM が指定された名前のクラスをクラスパス上で見つけられなかったときに出る。
設定が壊れているわけではなく、ほとんどは「渡した名前」か「クラスパスのルート」のどちらかが間違っている。

$ java Main
Error: Could not find or load main class Main
Caused by: java.lang.ClassNotFoundException: Main

続く Caused by:java.lang.ClassNotFoundException なら探索経路の問題である。UnsupportedClassVersionError などの LinkageError が続く場合は別問題なので、class file version の記事を参照する。

実行例

実際に上記の手順を eclipse-temurin:21-jdk で動かすと、.class のパスをそのまま渡した場合は区切りの /. に置き換わった out.com.example.App.class というクラスを探しに行き、パッケージ名の省略やクラスパスのルート違いと同じく ClassNotFoundException で終了コード 1 になった。-cp out と完全修飾名 com.example.App を組み合わせたときだけ App started が出力された。

$ java out/com/example/App.class
Error: Could not find or load main class out.com.example.App.class
Caused by: java.lang.ClassNotFoundException: out.com.example.App.class
終了コード: 1
$ java -cp out App
Error: Could not find or load main class App
Caused by: java.lang.ClassNotFoundException: App
終了コード: 1
$ java -cp out/com/example com.example.App
Error: Could not find or load main class com.example.App
Caused by: java.lang.ClassNotFoundException: com.example.App
終了コード: 1
$ find out -name *.class
out/com/example/App.class
$ java -cp out com.example.App
App started
終了コード: 0

— 2026-09-11 時点の出力

検証環境

検証日
実行環境
eclipse-temurin:21-jdkUbuntu 26.04.1 LTS

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

よくある原因

  1. 拡張子まで渡している: java Hello.class と打つと、JVM は Hello.class という名前のクラスを探すため必ず失敗する。.java を渡した場合はソースファイルモードとして別扱いになるので、症状が出るのは .class の方である。
  2. パッケージ名を省いている: package com.example; を持つクラスは、ディレクトリを移動しても短い名前では起動できない。
    JVM が受け取るのは常に完全修飾名である。
  3. クラスパスのルートがずれている: com/example/App.class に対するルートは com の親ディレクトリであって、com/example ではない。
  4. 出力先と実行時の指定が食い違っている: javac -d out で出したのに -cp を付けずに実行しているケースが多い。

解決策

1. 完全修飾クラス名で実行する

java com.example.App        # ○ 拡張子なし・パッケージ込み
java App                    # × パッケージ宣言があると失敗する
java com/example/App.class  # × 拡張子付きは失敗する

2. クラスパスのルートを -cp で指す

javac -d out src/com/example/App.java
java -cp out com.example.App

-cp を省略するとカレントディレクトリだけが探索対象になる。
ルート以外の場所から起動するなら明示が必要である。
詳細は java コマンドの公式ドキュメント(新しいタブで開く)にある --class-path の説明を参照する。

3. クラスファイルの実在を確認する

find . -name '*.class'
# ./out/com/example/App.class → ルートは ./out

出力されたパスからパッケージ階層をそのまま取り除いた部分がクラスパスのルートになる。

4. jar なら Main-Class を確認する

unzip -p app.jar META-INF/MANIFEST.MF

Main-Class: com.example.App の行が無い、または綴りが違うと java -jar で同じエラーになる。

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