[解決済み] Could not find or load main class "とはどういう意味ですか?
質問
新しいJava開発者が経験する共通の問題は、エラーメッセージとともにプログラムが実行されないことです。
Could not find or load main class ...
これは何を意味し、何が原因で、どのように修正すればいいのでしょうか?
解決方法は?
その
java <class-name>
コマンドの構文
まず最初に、プログラムを起動するために
java
(または
javaw
) コマンドを使用します。
通常の構文 1 はこうです。
java [ <options> ] <class-name> [<arg> ...]
ここで
<option>
はコマンドラインオプション("-"で始まる文字)です。
<class-name>
は完全修飾のJavaクラス名、そして
<arg>
は、アプリケーションに渡される任意のコマンドライン引数です。
1 - 他にもいくつかの構文があり、この回答の最後のほうに記載されています。
クラスの完全修飾名(FQN)は、慣習的にJavaのソースコードと同じように記述します。
packagename.packagename2.packagename3.ClassName
ただし、一部のバージョンでは
java
コマンドでは、ピリオドの代わりにスラッシュを使用することができます。
packagename/packagename2/packagename3/ClassName
は、(紛らわしいことに)ファイルのパス名のように見えますが、実際にはパス名ではありません。 という用語があることに注意してください。 完全修飾名 は、標準的なJavaの用語です...あなたを混乱させるために私が作ったものではありません :-)
以下は
java
コマンドは次のようになります。
java -Xmx100m com.acme.example.ListUsers fred joe bert
上記により
java
コマンドは次のようになります。
-
のコンパイル済みバージョンを検索します。
com.acme.example.ListUsers
クラスがあります。 - クラスを読み込む。
-
このクラスが
main
メソッドに シグネチャ , 戻り値タイプ と モディファイア によって与えられるpublic static void main(String[])
. (注、メソッドの引数の名前は NOT はシグネチャの一部です)。 -
コマンドライン引数 ("fred", "joe", "bert") を渡してそのメソッドを呼び出します。
String[]
.
Javaがクラスを見つけられない理由
Could not find or load main class ..."というメッセージが表示されたら、それは最初のステップに失敗したことを意味します。 その
java
コマンドはクラスを見つけることができませんでした。 そして実際、メッセージの中の "..." は、次のようになります。
完全修飾クラス名
その
java
が探している。
では、なぜそのクラスが見つからないのでしょうか?
理由その1 - classname 引数を間違えている。
まず考えられるのは、間違ったクラス名を指定したことです。 (あるいは...正しいクラス名だが間違った形式) 上記の例を考慮すると、以下のようなさまざまなものがあります。 間違った方法 のように、クラス名を指定します。
-
例1 - シンプルなクラス名。
java ListUser
などのパッケージでクラスが宣言されている場合、そのクラスは
com.acme.example
を使用する場合は、完全なクラス名 を含む のパッケージ名はjava
コマンドを使用します; 例.java com.acme.example.ListUser
-
例2 - クラス名ではなく、ファイル名またはパス名を指定する。
java ListUser.class java com/acme/example/ListUser.class
-
例3:ケーシングが正しくないクラス名。
java com.acme.example.listuser
-
例4:タイプミス
java com.acme.example.mistuser
-
例5 - ソースファイル名 (Java 11以降を除く。下記参照)
java ListUser.java
-
例6:クラス名を完全に忘れてしまった場合
java lots of arguments
理由その2:アプリケーションのクラスパスが正しく指定されていないため
2つ目の原因として考えられるのは、クラス名は正しいのですが、そのクラスの
java
コマンドでそのクラスを見つけることができません。 これを理解するためには、"classpath" の概念を理解する必要があります。 これは、次のように説明されています。
さて
は、Oracleのドキュメントに記載されています。
-
は
java
コマンドドキュメント - クラスパスの設定 .
- Javaチュートリアル PATHとCLASSPATH
さて......クラス名が正しく指定されていれば、次に確認するのはクラスパスが正しく指定されているかということです。
- 上記リンク先の3つのドキュメントを読んでみてください。 (そうです ... 読んでください。 Javaプログラマにとって重要なのは 理解する 少なくともJavaのクラスパスの仕組みの基本は知っておいてください)。
-
を実行したときに有効なコマンドラインと/またはCLASSPATH環境変数を見ます。
java
コマンドを実行します。 ディレクトリ名とJARファイル名が正しいかどうか確認してください。 -
がある場合
相対
を実行したときに有効なカレントディレクトリから、 クラスパスのパス名が正しく解決されることを確認します。
java
コマンドを実行します。 - エラーメッセージに記載されている)クラスが 有効 クラスパス
-
なお、クラスパスの文法は
異なる
の場合、Windows と Linux や Mac OS は異なります。(クラスパスのセパレータは
;
を使用し、Windowsでは:
を使用します。 もし、あなたのプラットフォームで間違ったセパレータを使用した場合、明確なエラーメッセージは表示されません。 その代わり、パス上に存在しないファイルやディレクトリが表示され、黙って無視されます)。
理由その2a - クラスパスに間違ったディレクトリが存在するため
クラスパスにディレクトリを置くと、それは概念的に修飾名空間のルートに対応します。 クラスは、そのルートの下のディレクトリ構造に配置されます。
完全修飾名をパス名にマッピングすることで
. したがって、例えば、"/usr/local/acme/classes"がクラスパスにある場合、JVMが
com.acme.example.Foon
というパス名のファイルを探します。
/usr/local/acme/classes/com/acme/example/Foon.class
もし、クラスパスに "/usr/local/acme/classes/com/acme/example" を置いたなら、JVMはクラスを見つけることができないでしょう。
理由その2b - サブディレクトリのパスがFQNと一致しない。
クラスのFQNが
com.acme.example.Foon
とすると、JVMはディレクトリ"com/acme/example"にある"Foon.class"を探そうとします。
-
もし、ディレクトリ構造が上記のパターンのようにパッケージの命名と一致しない場合、JVMはあなたのクラスを見つけることができません。
-
もし リネーム を移動させた場合も同様に失敗しますが、例外のスタックトレースは異なります。 このような表現になる可能性があります。
Caused by: java.lang.NoClassDefFoundError: <path> (wrong name: <name>)
クラスファイルの FQN がクラスローダーが期待するものと一致しないためです。
具体的な例を挙げると、仮に。
-
を実行したい場合
com.acme.example.Foon
クラスがあります。 -
の場合、ファイルのフルパスは
/usr/local/acme/classes/com/acme/example/Foon.class
, -
現在の作業ディレクトリは
/usr/local/acme/classes/com/acme/example/
,
では
# wrong, FQN is needed
java Foon
# wrong, there is no `com/acme/example` folder in the current working directory
java com.acme.example.Foon
# wrong, similar to above
java -classpath . com.acme.example.Foon
# fine; relative classpath set
java -classpath ../../.. com.acme.example.Foon
# fine; absolute classpath set
java -classpath /usr/local/acme/classes com.acme.example.Foon
注意事項
-
は
-classpath
オプションは、次のように短縮することができます。-cp
は、ほとんどのJavaリリースで については、それぞれのマニュアルのエントリを確認してください。java
,javac
といった具合です。 - クラスパスで絶対パス名と相対パス名のどちらを選択するかは、慎重に考えてください。 相対パス名は、カレント・ディレクトリが変更された場合に "break"する可能性があることを覚えておいてください。
理由その2c - クラスパスから依存関係が抜けている
クラスパスには、すべての その他 (非システム) クラスに依存しています。 (システムクラスは自動的に配置されるので、ほとんど気にする必要はありません)。 メインクラスが正しくロードされるために、JVMは以下を見つける必要があります。
- クラスそのもの。
- スーパークラス階層にあるすべてのクラスとインターフェイス(例えば Javaクラスはクラスパスに存在するが、起動時にError.で失敗する。Could not find or load main class )
- 変数や変数宣言、メソッド呼び出しやフィールドアクセス式によって参照されるすべてのクラスとインターフェース。
(注意:JLSとJVMの仕様では、JVMがクラスを"lazily"ロードするためのいくつかの範囲を認めており、これはクラスローダー例外が投げられるときに影響することがあります)。
理由その3:クラスが間違ったパッケージで宣言されている
時々、ソースコード・ファイルを
を省略した場合、あるいは
package
という宣言があります。 IDEでこのようなことをすれば、IDEのコンパイラがすぐに教えてくれるでしょう。 同様に、まともなJavaビルドツールを使っている場合、そのツールは
javac
を検出するようにします。 しかし、手作業でJavaコードをビルドする場合、コンパイラが問題に気づかないような方法でビルドしてしまい、結果として ".class" ファイルが期待した場所にないことがあるのです。
まだ問題が見つからない?
チェックすべき項目がたくさんあり、見落としが起こりがちです。 そこで
-Xdiag
オプションを
java
コマンドラインの
java
). クラスの読み込みに関する様々なことが出力され、本当の問題が何であるかを知る手がかりになるかもしれません。
また、Webサイトや文書などから見えない文字や非ASCII文字をコピー&ペーストすることで発生する可能性のある問題も考慮してください。 また、2つの文字や記号が同じように見えて、実は違うという「ホモグリフ」についても考えてみてください。
に無効または不正な署名がある場合、この問題に遭遇することがあります。
META-INF/*.SF
. お気に入りの ZIP エディターで .jar を開き、以下のファイルを削除してください。
META-INF
のみとなります。
MANIFEST.MF
. しかし、これは一般的には推奨されません。 (無効な署名は、誰かがオリジナルの署名付き JAR ファイルにマルウェアを注入した結果かもしれません。 無効な署名を消してしまうと、あなたのアプリケーションをマルウェアに感染させてしまうことになります!) 推奨されるアプローチは、有効な署名を持つJARファイルを入手するか、(本物の)オリジナルのソースコードからJARファイルを再構築することです。
最後に、この問題はどうやら
MANIFEST.MF
ファイル(参照
https://stackoverflow.com/a/67145190/139985
).
の代替構文
java
を使用してJavaプログラムを起動するには、3つの代替構文があります。
java command
.
-
実行可能なJARファイルの起動に使用される構文は以下のとおりです。
java [ <options> ] -jar <jar-file-name> [<arg> ...]
など
java -Xmx100m -jar /usr/local/acme-example/listuser.jar fred
エントリーポイントクラスの名前(つまり
com.acme.example.ListUser
) とクラスパスがJARファイルのMANIFESTに指定されています。 -
モジュールからアプリケーションを起動するための構文(Java 9以降)は、以下のとおりです。
java [ <options> ] --module <module>[/<mainclass>] [<arg> ...]
エントリポイントクラスの名前は
<module>
そのものか、あるいはオプションの<mainclass>
. -
Java 11 以降は
java
コマンドを使用すると、次の構文で1つのソースコード・ファイルをコンパイルして実行できます。java [ <options> ] <sourcefile> [<arg> ...]
ここで
<sourcefile>
は、(通常)接尾辞が ".java" であるファイルです。
の公式ドキュメントを参照してください。
java
コマンドを使用します。
IDE
典型的なJava IDEは、IDE JVM自体または子JVMでJavaアプリケーションを実行するためのサポートを持っています。 これらは
一般的に
IDEは独自のメカニズムでランタイムクラスパスを構築し、メインクラスを識別して
java
コマンドラインを使用します。
しかし、IDEの裏側でいろいろなことをすると、この例外が発生する可能性があります。 例えば、EclipseでJavaアプリのApplication Launcherを設定した後、"main"クラスを含むJARファイルをファイルシステム内の別の場所に移動した場合、この例外が発生します。 Eclipseに内緒で そのため、Eclipseは知らず知らずのうちに不正なクラスパスでJVMを起動することになります。
要するに、IDEでこの問題が発生した場合、IDEの状態が古くなっていないか、プロジェクトの参照が壊れていないか、ランチャーの設定が壊れていないかなどを確認します。
また、IDEが単に混乱している可能性もあります。 IDEは、多くの相互作用する部分からなる非常に複雑なソフトウェアの一部です。 これらのパーツの多くは、IDE が全体として応答するように、さまざまなキャッシュ戦略を採用しています。 これらは時々うまくいかないことがあり、可能性のある症状の1つは、アプリケーションの起動時の問題です。 このような現象が発生する可能性がある場合、IDE を再起動したり、プロジェクトを再構築するなど、他の方法を試してみる価値があります。
その他のリファレンス
- Oracle Java チュートリアル - より よくある問題(とその解決策)
関連
-
スレッド "main" での例外 java.lang.ArrayIndexOutOfBoundsException: 1
-
アイデア Springboot Web プロジェクトを jar にパッケージ化する場合、Error: 無効または破損した jarfile x.jar 解決策
-
Maven Pluginの実行がライフサイクル設定の対象外であるエラーの解決
-
[解決済み] java.lang.UnsupportedClassVersionError を修正する方法。サポートされていないメジャー.マイナーバージョン
-
[解決済み] シンクロナイズド」とはどういう意味ですか?
-
[解決済み] Eclipseが起動できない - Javaは起動したが終了コード=13を返した
-
[解決済み] 残念ながらMyAppは停止してしまいました。どうすればよいですか?
-
[解決済み] Cannot find symbol" や "Cannot resolve symbol" というエラーはどういう意味ですか?
-
[解決済み】if __name__ == "__main__": は何をするのでしょうか?
-
[解決済み】Javaの「ダブルブレース初期化」の効率化?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
Java のエラーです。未解決のコンパイル問題 解決方法
-
eclipse で「アクセス制限: タイプ 'HttpServer' は API ではありません」というプロンプトが表示される。
-
Android Studio 3.1.2 で v4, v7 パッケージが見つからない シンボル 'AppCompatActivity' を解決できない
-
プロジェクトの依存関係を解決できなかった 解決
-
エラーの解決方法 jarfile XXX.jarにアクセスできません。
-
spring-boot 401 このリソースにアクセスするには完全な認証が必要です エラー解決
-
このラインで複数のマーカーを解決する方法
-
Google Chromeのエラー「Not allowed to load local resource」の解決策について
-
Maven Pluginの実行がライフサイクル設定の対象外であるエラーの解決
-
[解決済み] エラーです。メインクラスが見つからない、またはロードできない [重複] 。