「メインクラスを見つけられなかったか、ロードできませんでした」とはどういう意味ですか?


1370

新しいJava開発者が経験する一般的な問題は、プログラムがエラーメッセージで実行に失敗することです。 Could not find or load main class ...

これは何を意味し、何が原因で、どのように修正する必要がありますか?


37
これは「自己回答」の質問であり、新しいJavaユーザー向けの一般的なリファレンスQ&Aであることに注意してください。これを十分にカバーする既存のQ&Aは見つかりませんでした(IMO)。
スティーブンC

回答:


1230

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コマンドは次のことを実行します。

  1. com.acme.example.ListUsersクラスのコンパイル済みバージョンを検索します。
  2. クラスをロードします。
  3. クラスに、シグネチャ戻り値の型、およびによって指定された修飾子を持つmainメソッドがあることを確認してください。(メソッドの引数の名前は署名の一部ではないことに注意してください。)public static void main(String[])
  4. コマンドライン引数( "fred"、 "joe"、 "bert")をとして渡してそのメソッドを呼び出しString[]ます。

Javaがクラスを見つけられない理由

「メインクラスを見つけられなかったか、ロードできませんでした...」というメッセージが表示された場合、それは最初のステップが失敗したことを意味します。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コマンドがクラスを見つけられないことです。これを理解するには、「クラスパス」の概念を理解する必要があります。これはOracleのドキュメントでよく説明されています。

したがって、クラス名を正しく指定した場合、次にチェックすることは、クラスパスを正しく指定したことです。

  1. 上記の3つのドキュメントを読んでください。(はい...読んでください!Javaプログラマー少なくともJavaクラスパスメカニズムの仕組みの基本を理解していることが重要です。)
  2. コマンドラインまたはjavaコマンドを実行したときに有効なCLASSPATH環境変数を確認します。ディレクトリー名とJARファイル名が正しいことを確認してください。
  3. クラスパスに相対パス名がある場合は、それらが正しく解決されることを確認してください... javaコマンドを実行したときに有効な現在のディレクトリから。
  4. クラス(エラーメッセージに示されている)が有効なクラスパスにあることを確認します。
  5. クラスパス構文は、WindowsとLinuxおよびMac OSでは異なります。(クラスパスセパレーターは;Windowsと:その他にあります。プラットフォームで間違ったセパレーターを使用すると、明示的なエラーメッセージは表示されません。代わりに、存在しないファイルまたはディレクトリがパス上に表示され、暗黙的に無視されます。 。)

理由#2a-クラスパスに間違ったディレクトリがあります

クラスパスにディレクトリを置くと、それは概念的には修飾された名前空間のルートに対応します。クラスは、完全修飾名をパス名にマッピングすることにより、そのルートの下のディレクトリ構造に配置されます。たとえば、「/ usr / local / acme / classes」がクラスパス上にある場合、JVMはというクラスを探すときに、次のcom.acme.example.Foonパス名を持つ「.class」ファイルを探します。

  /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リリースで短縮できます。以下のために、それぞれのマニュアルのエントリをチェックしjavajavacそして上のようにします。
  • クラスパスで絶対パス名と相対パス名のどちらを選択するかを慎重に検討してください。現在のディレクトリが変更されると、相対パス名が「壊れる」可能性があることに注意してください。

理由#2c-依存関係がクラスパスにない

クラスパスには、アプリケーションが依存する他のすべて(非システム)クラスを含める必要があります。(システムクラスは自動的に配置されるため、これを気にする必要はほとんどありません。)メインクラスが正しくロードされるためには、JVMは以下を見つける必要があります。

(注:JLSおよびJVM仕様では、JVMがクラスを「遅延して」ロードするためのスコープが許可されており、これはクラスローダー例外がスローされたときに影響する可能性があります。)

理由#3-クラスが間違ったパッケージで宣言されています

誰かがソースコードファイルをソースコードツリーの間違ったフォルダに配置したり、package宣言を省略したりすることがあります。IDEでこれを行うと、IDEのコンパイラーはこれについてすぐに通知します。同様に、適切なJavaビルドツールを使用すると、ツールはjavac問題を検出する方法で実行されます。ただし、Javaコードを手動で作成する場合は、コンパイラーが問題に気付かず、結果の「.class」ファイルが予期した場所にないような方法で作成できます。

まだ問題が見つかりませんか?

確認することはたくさんありますが、見落としがちです。コマンドラインに-Xdiagオプションを追加してみてくださいjava(最初のとしてjava)。クラスローディングに関するさまざまなことを出力し、これは実際の問題が何であるかについての手がかりを提供するかもしれません。

また、Webサイトやドキュメントなどから非表示の文字または非ASCII文字をコピーして貼り付けることによって発生する可能性のある問題についても検討してください。「ホモグリフ」を考えてみてください。2つの文字または記号が同じように見えますが、そうではありません。

最後に、で不正な署名のあるJARファイルから起動しようとすると、明らかにこの問題が発生する可能性があります(META-INF/*.SF)


の代替構文 java

を使用してJavaプログラムを起動するには、3つの代替構文がありますjava command

1)「実行可能」JARファイルの起動に使用される構文は次のとおりです。

  java [ <options> ] -jar <jar-file-name> [<arg> ...]

例えば

  java -Xmx100m -jar /usr/local/acme-example/listuser.jar fred

エントリポイントクラスの名前(つまりcom.acme.example.ListUser)とクラスパスは、JARファイルのMANIFESTで指定されます。

2)モジュール(Java 9以降)からアプリケーションを起動するための構文は次のとおりです。

  java [ <options> ] --module <module>[/<mainclass>] [<arg> ...]

エントリポイントクラスの名前は、<module>それ自体によって定義されるか、オプションで指定されます<mainclass>

3)Java 11以降では、単一のソースコードファイルをコンパイルして実行し、次の構文で実行できます。

  java [ <options> ] <sourcefile> [<arg> ...]

ここで、(通常)は「.java」というサフィックスが付いたファイルです。

詳細については、java使用しているJavaリリースのコマンドの公式ドキュメントを参照してください。


IDE

典型的なJava IDEは、IDE JVM自体または子JVMでのJavaアプリケーションの実行をサポートしています。IDEは独自のメカニズムを使用してランタイムクラスパスを構築し、メインクラスを識別してコマンドラインを作成するため、これらは通常、この特定の例外の影響を受けませんjava

ただし、IDEの背後で何かを行うと、この例外が発生する可能性があります。たとえば、以前にEclipseでJavaアプリのアプリケーションランチャーを設定していて、「メイン」クラスを含むJARファイルをEclipseに通知せずにファイルシステムの別の場所に移動した場合、Eclipseは意図せずにJVMを起動しますクラスパスが正しくありません。

つまり、IDEでこの問題が発生した場合は、古いIDEの状態、壊れたプロジェクト参照、壊れたランチャー構成などを確認してください。

IDEが単に混乱する可能性もあります。IDEは非常に複雑なソフトウェアであり、相互作用する多くの部分で構成されています。これらのパーツの多くは、IDE全体を応答可能にするために、さまざまなキャッシュ戦略を採用しています。これらは時々失敗する可能性があり、1つの考えられる症状は、アプリケーションの起動時の問題です。これが発生していると思われる場合は、IDEの再起動、プロジェクトの再ビルドなど、他のことを試す価値があります。


その他の参考資料


43
サードパーティのライブラリでクラスを実行しようとしたときに、この問題が発生しました。私は次のようにjavaを呼び出しました:java -cp ../third-party-library.jar com.my.package.MyClass; これは機能しません。代わりに、ローカルフォルダーもクラスパスに追加する必要があります(次の:ようにで区切られます:java -cp ../third-party-library.jar:. com.my.package.MyClass、それから機能するはずです
lanoxx

23
長年のJavaプログラミングの後、私はまだこのページにたどり着きました。私にとっての問題は、クラスパス構文がOSに依存することでした。私はWindowsでプログラミングをするのが初めてで、まったくわかりませんでした。
キーヤー2015年

5
追加のメモ、ポイント2は私を救います!javaインポートされたクラスが見つからないというのではなく、実行しようとしているメインクラスが表示されないのは残念です。これには誤解がありますが、その理由は確かです。java私のクラスがどこにあるかを正確に知っているケースがありましたが、インポートされたクラスの1つを見つけることができませんでした。それを言う代わりに、それは私のメインクラスを見つけられないことについて不平を言いました。本当に、うんざり。
MSX

私はEclipseでこの問題を2回経験しました。main()の署名が初めて間違っていました。2回目に.jarの名前を変更し、新しいパスをビルドパスに追加したにもかかわらず、Eclipseは古いパスを見つけられなかったため、プロジェクトはコンパイルされず、このエラーが発生しました。プロジェクト>プロパティ> Javaビルドパス>ライブラリから.jarファイルを削除する必要がありました。
GregT 2018年

3回目に遭遇しました。Windows 10のバッチファイルからプログラムを実行し、.jar名を変数に入れました( "-cp%jarname%; lib *"で呼び出されます)。誤ってjarnameの最後に余分なスペースを入れてしまい、エラーが発生しました。ハットトリック:)
GregT 2018年

239

ソースコード名がHelloWorld.javaの場合、コンパイルされたコードはになりますHelloWorld.class

次を使用して呼び出すと、そのエラーが発生します。

java HelloWorld.class

代わりに、これを使用してください:

java HelloWorld

3
問題は、このソリューションがデフォルトのパッケージで宣言されたJavaクラスに対してのみ機能し、JARファイルの依存関係がないことです。(そしてそれでも、常にではありません。)ほとんどのJavaプログラムはそれほど単純ではありません。
スティーブンC

1
スティーブンが言ったように、これは「デフォルトのパッケージ」でのみ機能します-これはファイルの先頭にパッケージ宣言がないことを意味します。いくつかのコードを簡単にテストするために、私は次のことをjavac TestCode.java行いました。続いてjava TestCode
Someone Somewhere

これは私にはうまくいきませんでした。それでも、「メインクラスHelloWorldを見つけられなかったか、ロードできませんでした」
Jim

java -jar HelloWorld.jarもオプションです
BMaximus

12
私はやらなければなりませんでしたjava -classpath . HelloWorld
クリス・プリンス

136

クラスがパッケージ内にある場合はcd、プロジェクトのルートディレクトリに移動し、クラスの完全修飾名(packageName.MainClassName)を使用して実行する必要があります。

例:

私のクラスはここにあります:

D:\project\com\cse\

私のメインクラスの完全修飾名は次のとおりです。

com.cse.Main

cdルートプロジェクトディレクトリに戻ります。

D:\project

次に、javaコマンドを発行します。

java com.cse.Main

この回答は、よくある間違いによって引き起こされるフラストレーションから初心者のJavaプログラマーを救うためのものです。Javaクラスパスについての詳細な知識については、受け入れられた回答を読むことをお勧めします。


2
この答えは、たくさんの仮定をします。そして、これを達成する他の方法があります。上記のアドバイスを盲目的に実行するのではなく、Javaクラスパスのしくみを説明する私の回答のリンクを読むことをお勧めします。あなたが何をしているのか理解する方がいいです...
スティーブンC

2
この答えは、私が必要とする正確な仮定を行います:)私は.classファイルのディレクトリにあり、java.exeが機能していませんでした。上記でcdを実行し、コマンドラインに含まれているパッケージ名で実行すると、動作しました。
ニックコンスタンティン

61

メインクラスとメインメソッドをで定義する場合packageは、クラスの完全な名前(packageName.MainClassName)を使用して、階層ディレクトリで実行する必要があります。

ソースコードファイル(Main.java)があると仮定します。

package com.test;

public class Main {

    public static void main(String[] args) {
        System.out.println("salam 2nya\n");
    }
}

このコードを実行するにMain.Classは、ディレクトリのようなパッケージに配置する必要があります./com/test/Main.Java。そして、ルートディレクトリでを使用しますjava com.test.Main


1
私の回答の「付記1」をご覧ください。この問題のより良い説明のために。
スティーブンC

14
@StephenCはい、あなたの答えはより完全です(そしてもちろん+1です)が、この特定の答えには「パッケージ」という単語が含まれていたため、必要なものをすばやく見つけることができました。そしてそれはうまくいった。だから+1ラザビ。StephenC、私はJavaが初めてなので、必要な簡単なパッケージの例がありません。
kmort 2014年

5
これはまさに私の問題でした。私は大量のJavaドキュメントを調べてきましたが、この具体的な例は私が必要としていたものです
John

1
はい、具体的な例はいいですが、これは完璧に機能しました。正解はきちんと答えられていると思いますが、森の樹を見ることは難しかったです。ナイスワン@ラザビ
ピクセル

1
私は受け入れられたものではなく、この短くて役に立つ答えが好きです!
Spara

46

同じコードが1台のPCで機能しても、別のPCでエラーが表示される場合、私が見つけた最良の解決策は、次のようにコンパイルすることです。

javac HelloWorld.java
java -cp . HelloWorld

2
これはお勧めできません。CLASSPATH環境変数が設定されていないか、「。」と一致する値を持っているかに依存しています。はい、多くの場合機能しますが、それ以外の場合は機能しません。
スティーブンC

まあ確かにうまくいったjavac -classpath . HelloWorld.javaでしょう!そして、それはあなたの場合にはより良い解決策です。
スティーブンC

2
最初の行に「パッケージcom.some.address」がある場合-これは機能しません。あなたは..「パッケージアドレス」コメントアウトする必要があります
ジョー・

1
@Joe-そのハック(パッケージをコメント化)は(場合によっては)機能しますが、悪い考えです。より良いアイデアは、問題の原因を学び、理解し、正しい解決策を実装することです。
スティーブンC

36

たとえば、コマンドラインでクラスパスを指定するのに役立ちました。

  1. 新しいフォルダを作成し、 C:\temp

  2. C:\temp次のクラスを含むTemp.javaファイルをで作成します。

    public class Temp {
        public static void main(String args[]) {
            System.out.println(args[0]);
        }
    }
  3. folder C:\tempでコマンドラインを開き、次のコマンドを記述してTempクラスをコンパイルします。

    javac Temp.java
  4. コンパイルされたJavaクラスを実行し、クラスの-classpath場所をJREに知らせるオプションを追加します。

    java -classpath C:\temp Temp Hello!

3
Ubuntuでは、パスも指定する必要がありました。デフォルトで現在の作業ディレクトリを使用できない理由を理解していない。Javaはキーボードの製造元によって提供されていると私は確信しています!!
2014

1
@gone-「。」という理由 デフォルトでは$ PATHにありませんが、これはセキュリティトラップです。 seas.upenn.edu/cets/answers/dot-path.html
スティーブンC

環境変数に設定した後でもJavaがクラスパスを見つけることができなかった理由がわからない場合でも、これに感謝します。
akash89

@ akash89 -最も可能性が高い理由はされた:1)をjava使用すると、クラスパスの設定はありませんでした環境で設定されていなかった-classpathまたは-jar)または2)を使用しているため($ CLASSPATHを見ていていなかった効果でコンテキストでjavaいました実行; たとえば、正しいシェルにsetenvコマンドを追加したファイルを「ソース」しなかったためです。
スティーブンC

それでもエラーが発生する:メインクラスTempが見つからないか、ロードできませんでした。
スター

27

エラーメッセージ(「メインクラスが見つからないか、ロードできませんでした」)によると、問題には次の2つのカテゴリがあります。

  1. メインクラスが見つかりませんでした
  2. メインクラスをロードできませんでした(このケースは、承認された回答で完全に説明されていません)

メインクラスがすることができませんでしがあるときにタイプミスや間違った構文が完全修飾クラス名にまたはそれが提供するクラスパスに存在しません

クラスを開始できないときにメインクラスをロードできませんでした。通常、メインクラスは別のクラスを拡張し、そのクラスは提供されたクラスパスに存在しません。

例えば:

public class YourMain extends org.apache.camel.spring.Main

camel-springが含まれていない場合、このエラーが報告されます。


「基本的に」他にもたくさんのカテゴリーがあります。そして、欠落しているスーパークラスの問題は非常に珍しいサブケースです。(私が見たことがないほど珍しい...このサイトで尋ねられた質問では。)
Stephen C

エラーは「メインクラスを検索またはロードできませんでした」という理由で2つあります。他のカテゴリがある場合は、教えてください。私はそれを見たので、ここでそれを共有したいだけかもしれません。
Xiao Peng-ZenUML.com 2015

1
「この特定のエラーを回避するには、メインクラスを開始するために必要なすべてのクラスを含める必要があります」のようなものに変更します。私はあなたを説得しようとはしていません。それは私が見たい方法です。このように読みたい人のために、ここに答えを残しました。この議論をこれ以上拡張しないでください:)私は自分の発言を「受け入れられた回答で完全に議論されていない」に変更し、気分が良くなることを願っています。
Xiao Peng-ZenUML.com 2015

5
この情報は重要であり、明示的な言及に値します(これが言及する唯一の回答ですextends)。メインクラスが見つからなかった別のクラスを拡張するためにロードに失敗したときに、java が実際のクラスが見つからなかったことを報告しない(とは異なり)という難しい方法を学んだところです。ですから、そうなります。これを知らないのは、髪を引っ張るような状況です。NoClassDefFoundError
Hugues M.

1
この状況では、どの依存関係クラスがロードに失敗しているかを正確に知る方法はありますか?
カルロスA.イバラ

16

この場合、私はそのようなエラーがありました:

java -cp lib.jar com.mypackage.Main

それはで動作する;Windows用と:Unix用:

java -cp lib.jar; com.mypackage.Main

はい。MainJARファイルに含まれていないことが原因であると考えられます。 つまり、現在のディレクトリがクラスパスに含まれて-cp lib.jar;いるのと同じことを意味し-cp lib.jar;.ます。
Stephen C

UNIXの問題を最後に修正しました..感謝(:で動作)
Vicky

16

-Xdiagを試してください。

スティーブCの答えはうまく可能なケースをカバーし、時にはクラスができなかったかどうかを判断するために見つけるか、ロードされたことは容易ではないかもしれません。使用しますjava -Xdiag(JDK 7以降)。これは、メッセージCould not find or load main classメッセージが何を意味するかについてのヒントを提供する素晴らしいスタックトレースを出力します。

たとえば、メインクラスが使用できなかった他のクラスを見つけることができず、メインクラスをロードできなかった可能性があります。


16

次のコマンドを使用します。

java -cp . [PACKAGE.]CLASSNAME

例:クラス名がHello.javaから作成されたHello.classの場合、次のコマンドを使用します。

java -cp . Hello

Hello.javaファイルがcom.demoパッケージ内にある場合は、次のコマンドを使用します。

java -cp . com.demo.Hello

JDK 8では、クラスファイルが同じフォルダーに存在するjavaことがよくありますが、コマンドはクラスパスを想定しているため-cp .、現在のフォルダーをクラスパスの参照として使用するように追加します。


これは単純な場合にのみ機能します。より複雑なケースでは、より複雑なクラスパスが必要です。
スティーブンC

また、>> really <<の単純なケースの場合-cp .は不要です。なぜなら、$CLASSPATHが設定されていない場合.は、がデフォルトのクラスパスだからです。
スティーブンC

いいえ、スティーブンは、Windowsのデフォルトのクラスパスで何度も機能しません。私は3つの異なるマシンで試してみましたが、あなたもそれを試すことができます。
shaILU

これはおそらく、実際に%CLASSPATH%環境変数をどこかに設定したためです。その場合、デフォルトのクラスパスを使用していません。(何がecho %CLASSPATH%出力されますか?)そして、いいえ、Windows PCを持っていないので確認できません。
スティーブンC

2
これは、コマンドラインから単純なプログラムを実行しようとしたときに
うまくいきました

15

時々問題を引き起こしているかもしれないことがメインクラスとは何の関係もない、そして私はこれを難しい方法で見つけなければならなかった。それは私が移動した参照ライブラリであり、それは私に以下を与えました:

メインクラスxxx Linuxを検出またはロードできませんでした

その参照を削除して再度追加したところ、再び正常に機能しました。


1
IDEのプロジェクトで「参照」が壊れているために、クラスパスが正しくなかったことが問題のようです。そのケースをカバーするために私の答えを更新します。
スティーブンC

@StephenCおよびEduardoDennis、ここでも、jarが欠落しており、そのjarには、インスタンス化するためにメインクラスが依存するインターフェースが含まれていました。したがって、エラーメッセージは広すぎます。クラスファイルが見つからない場合は「見つかりませんでした」、ファイル自体ではなく他に不足しているものがある場合は「ロードできませんでした(依存関係がありません)」と言う必要があるため、焦点を合わせるだけでは、エラーメッセージが広すぎて誤解を招く可能性がありますその「検索」部分:(
Aquarius Power

@AquariusPower-クラスが欠落していると言う「原因」例外の追加の「原因」スタックトレースがあったはずです。20年以上前から言われているエラーメッセージを変更するようにJava開発者に提案したい場合は... (エラーメッセージは正しいと思います。問題は>> you <<が間違った句を絞り込んだことです。)
Stephen C

@StephenC私が言ったことは、メインクラスファイルが利用可能かどうかにかかわらず、情報に確実にアクセスできることです。一方、その時点で「ファイルは見つかりましたがロードできませんでした」と言うこともできるので、理解するために調査とテストを半日行うのではなく、依存関係に迅速に集中します。ちょうど私が意味した:)。彼らは20年以上の限られた方法でそれを行うかもしれませんが、彼らはそれを改善することができ、私たちは私たちの批判と不満を通して起こることを認めるためにここにいます!:D
Aquarius Power

>> I <<の意味を理解してください。3歳のQ&Aに関するあいまいなコメントでそれについて不平を言っても、何も達成されません。あなたの不満に対して信頼できる行動をとる可能性のある人々は、それに気づかないでしょう。建設的なことをしたい場合は、パッチを提出してください。(私はあなたの可能性を評価しませんが、あなたがそれについてただ口にした場合よりも大きくなります。)
スティーブンC

10

この場合、次のようになります。

メインクラスが見つからないか、ロードできませんでした?クラスパス

"-classpath"を使用しているためですが、ダッシュはjavaコマンドプロンプトで使用されるダッシュとは異なります。この問題は、メモ帳からcmdへのコピーアンドペーストで発生しました。


2
うわー!それは完全に奇妙な原因です!(ただし、実際のテキストエディターの代わりにメモ帳を使用するのに適しています:
Stephen C

10

私は同じ問題を抱えていて、ついに私の間違いを発見しました:)私はこのコマンドをコンパイルに使用し、正しく機能しました:

javac -cp "/home/omidmohebbi/AAAATest/jars/core-1.7.jar:/home/omidmohebbi/AAAATest/jars/javase-1.7.jar:/home/omidmohebbi/AAAATest/jars/qrgen-1.2.jar" qrcode.java

しかし、このコマンドは私にとってはうまくいきませんでした(メインクラスを見つけたりロードしたりできませんでしたqrcode):

java -cp "/home/omidmohebbi/AAAATest/jars/core-1.7.jar:/home/omidmohebbi/AAAATest/jars/javase-1.7.jar:/home/omidmohebbi/AAAATest/jars/qrgen-1.2.jar" qrcode

最後に、クラスパスの最後に「:」文字を追加しただけで、問題は解決しました。

java -cp "/home/omidmohebbi/AAAATest/jars/core-1.7.jar:/home/omidmohebbi/AAAATest/jars/javase-1.7.jar:/home/omidmohebbi/AAAATest/jars/qrgen-1.2.jar:" qrcode

7

私の場合、クラス名の代わりにソースファイル名を指定したため、エラーが表示されました。

mainメソッドを含むクラス名をインタープリターに提供する必要があります。


はい。クラス名を指定する間違った方法の私の例2を参照してください!!
スティーブンC

7

これは、あなたのケースが特に私の場合に役立つかもしれません。初心者として、Javaプログラムを実行しようとしたときにこの問題にも遭遇しました。

私はそれを次のようにコンパイルしました:

javac HelloWorld.java

そして私は同じ拡張子で実行しようとしました:

java Helloworld.java

を削除しての.javaようjava HelloWorldにコマンドを書き換えると、プログラムは完全に実行されました。:)


2
これは、コンパイルされたバージョンの.javaを実行しているためです。実際には.classファイルを実行しています
Jason V

記録としては、これは理由#1と同じです。私の回答の例#5
Stephen C

6

ここでのすべての回答は、Windowsユーザーを対象としています。Macの場合、クラスパス区切り文字は:ではなく;です。使用するクラスパスの設定エラー;がスローされないため、WindowsからMacに移行する場合、これを見つけるのは困難です。

以下は対応するMacコマンドです。

java -classpath ".:./lib/*" com.test.MyClass

この例では、パッケージがcom.testあり、libフォルダーもクラスパスに含まれます。


2
LinuxでもMacと同じように。
Alex78191 2017年

なぜ/*必要なのですか?
Alex78191 2017年

これはワイルドカード構文です。(必須ではありません。必要に応じて、JARを明示的にリストできます。)
Stephen C

6

ここに画像の説明を入力してください

クラスファイルの場所: C:\ test \ com \ company

ファイル名: Main.class

完全修飾クラス名: com.company.Main

コマンドラインコマンド:

java  -classpath "C:\test" com.company.Main

クラスパスには\ com \ companyが含まれていないことに注意してください


6

私はこの問題を解決するためにかなりの時間を費やしました。私はどういうわけかクラスパスを間違って設定していると思いましたが、問題は入力したことでした:

java -cp C:/java/MyClasses C:/java/MyClasses/utilities/myapp/Cool  

の代わりに:

java -cp C:/java/MyClasses utilities/myapp/Cool   

完全修飾の意味は、完全なパッケージ名の代わりに完全なパス名を含めることだと思いました。


私はその混乱に対処するために私の答えを更新しました。
Stephen C

2
これらはどちらも正しくありません。クラスにutilities.myapp.Coolは、そのパッケージ名が存在する場合は、その名前を指定する必要があります。
ローンの侯爵

5

まず、このコマンドを使用してパスを設定します。

set path="paste the set path address"

次に、プログラムをロードする必要があります。保存したドライブに「cd(フォルダ名)」と入力してコンパイルします。たとえば、プログラムがDドライブに保存されている場合は、「D:」と入力してEnterキーを押し、「cd(フォルダ名)」と入力します。


4
これは役に立ちません。この質問は、通常の実行可能ファイルではなく、Javaプログラムに関するものです。JavaはPATHを使用して何かを検索することはありません。「cd」が役立つ場合は、判断ではなく運により検索されます。
スティーブンC

if "cd" helps then it by luck rather than by judgement。javaは.デフォルトで現在のディレクトリをクラスパスの一部として使用するため、これは誤りです(私は信じています)。
GKFX 2014年

2
@GKFX-それが私の意味です。デフォルトのクラスパス(または「。」が付いたクラスパス)を使用していることがわかっていない限り、「cd」は効果がありません。このソリューションは、判断(つまり、「。」がクラスパス上にあることを確認する)よりも運(つまり、「。」がクラスパス上にあることを推測/期待すること)によって機能します。さらに、あなたはデフォルトについて間違っています。Javaは「。」を使用します。デフォルトではクラスパスとしてではなく、デフォルトでクラスパスとして。
スティーブンC

5

私の場合の問題を修正したのは:

実行するプロジェクト/クラスを右クリックし、次にRun As->をクリックしますRun Configurations。次に、既存の構成を修正するか、次の方法で新規に追加する必要があります。

Classpathタブを開き、Advanced...ボタンをクリックして、プロジェクトのbinフォルダーを追加します


5

Mavenを使用してJARファイルを構築する場合は、必ずpom.xmlファイルでメインクラスを指定してください。

<build>
    <plugins>
        <plugin>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <mainClass>class name us.com.test.abc.MyMainClass</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>

4

これは特定のケースですが、このページにアクセスして解決策を探したが見つからなかったため、ここに追加します。

Windows(7でテスト済み)ではá、クラス名とパッケージ名に特殊文字(など)を使用できません。ただし、Linuxにはあります。

これは.jar、NetBeans をビルドしてコマンドラインで実行しようとしたときにわかりました。NetBeansでは実行されましたが、コマンドラインでは実行されませんでした。


4

Windowsでは.;、最初にCLASSPATH値を指定します。

。(ドット)は、「現在のディレクトリを探す」ことを意味します。これは永続的な解決策です。

また、setで「1回」に設定することもできますCLASSPATH=%CLASSPATH%;.。これは、cmdウィンドウが開いている限り続きます。


1
このアドバイスは役立つかもしれませんし、役に立たないかもしれません。現在のディレクトリにクラスを含むクラスツリーがある場合に役立ちます。そうでない場合はそうなりません。私は実際にはこれをしません。代わりに、ユーザーが「正しい」ディレクトリにいるかどうかに関係なく機能する1行のラッパースクリプトを作成します。
Stephen C

4

これはsrcフォルダから行う必要があります。そこで、次のコマンドラインを入力します。

[name of the package].[Class Name] [arguments]

クラスがという名前CommandLine.classで、コードが次のようになっているとします。

package com.tutorialspoint.java;

    /**
     * Created by mda21185 on 15-6-2016.
     */

    public class CommandLine {
        public static void main(String args[]){
            for(int i=0; i<args.length; i++){
                System.out.println("args[" + i + "]: " + args[i]);
            }
        }
    }

次にcd、srcフォルダーに移動すると、実行する必要のあるコマンドは次のようになります。

java com.tutorialspoint.java.CommandLine this is a command line 200 -100

また、コマンドラインの出力は次のようになります。

args[0]: this
args[1]: is
args[2]: a
args[3]: command
args[4]: line
args[5]: 200
args[6]: -100

2
クラスを「CommandLine.class」と呼ぶことはできません。これはJava構文エラーになります。(つまり、コンパイルされたクラスを含むファイルは "CommandLine.class"と呼ばれます...)。もう1つの問題は、「ソースディレクトリにcdする」という指示が機能するのは、コードをソースディレクトリツリーに>> <<コンパイルした場合のみです。最後に、コンパイルで「-cp」引数を使用した場合は、実行時に同等のものが必要です。
スティーブンC

私のプロジェクトでは、ルートにsrcフォルダーとbinフォルダーがあります。私は自分で機能するコマンドを実行cdsrcてから実行するjava ../bin com.blah.blah.MyClass必要がありました。先端をありがとう!
tamj0rd2

3

Javaでは、Java実行可能ファイルを使用してコマンドラインからJVMを実行し、public static void main(PSVM)を使用してクラスファイルからプログラムを起動しようとすると、クラスパスパラメーターがJVMは正確であり、クラスファイルはクラスパスに存在します。

Error: main class not found or loaded

これは、PSVMを含むクラスファイルをロードできなかった場合に発生します。考えられる理由の1つは、クラスがインターフェイスを実装しているか、クラスパス上にない別のクラスを拡張している可能性があることです。通常、クラスがクラスパスにない場合、スローされるエラーはそのことを示します。ただし、使用中のクラスが拡張または実装されている場合、javaはクラス自体をロードできません。

リファレンス:https : //www.computingnotes.net/java/error-main-class-not-found-or-loaded/


1
受け入れられた回答を読みましたか?あなたの答えは何か新しいことを追加しますか?
Stephen C

1
@StephenC「理由」カテゴリとそのポイントを見て、リストから理由を見つけようとしました。「理由#1」と「理由#2」のタイトルに一致する点が見つかりませんでした(クラスパス自体に問題がないと確信していたため)。実験を行って理由を見つけましたが、実装しているインターフェイスがクラスパス上になかったため、私の場合は「メインクラスが見つかりません」というエラーが表示されたことに驚きました。「投稿に記載されているすべてを読む必要があります」と言うことはできますが、理由リストは改善できるようです。
ガムキン

3

Windows PowerShellでアドバタイズされjava-cpオプションを使用してを実行すると、次のようなエラーが表示される場合があります。

The term `ClassName` is not recognized as the name of a cmdlet, function, script ...

PowerShellがコマンドを受け入れるためには、-cpオプションの引数を次のように引用符で囲む必要があります。

java -cp 'someDependency.jar;.' ClassName

この方法でコマンドを作成すると、Javaがクラスパス引数を正しく処理できるようになります。


3

Java MongoDB JDBC接続のテスト中にも、同様のエラーに直面しました。私の最終的な解決策を要約すると、将来的に誰もが2つのコマンドを直接調べることができ、さらに先に進むことができるようになるので、良いと思います。

Javaファイルと外部依存関係(JARファイル)が存在するディレクトリにいるとします。

コンパイル:

javac -cp mongo-java-driver-3.4.1.jar JavaMongoDBConnection.java
  • -cp-クラスパス引数。すべての依存JARファイルを1つずつ渡します
  • * .java-これは、mainメソッドを持つJavaクラスファイルです。sdsd

実行:

java -cp mongo-java-driver-3.4.1.jar: JavaMongoDBConnection
  • すべての依存関係JARファイルが終了したら、コロン(Unix)/コンマ(Windows)を確認してください
  • 最後に、拡張子なしのメインクラス名を確認します(.classまたは.javaはありません)。

これはすべて、1)JavaMongoDBConnectionパッケージがないこと、2)ディレクトリを変更しないことを前提としています。控えめに言っても、それは壊れやすいです。そして、問題を説明しないことで、初心者はそれが機能しない状況でこのアプローチを試すようになります。つまり、「ブードゥープログラミングテクニック」を奨励します。en.wikipedia.org
Stephen C

3

大丈夫、すでに多くの答えがありますが、ファイルのアクセス許可が犯人になる可能性があるケースについて誰も言及しませんでした。

実行中、ユーザーはJARファイルまたはパスのディレクトリの1つにアクセスできない場合があります。たとえば、次のことを考慮してください。

jarファイル /dir1/dir2/dir3/myjar.jar

JARファイルを所有するUser1は、次のことを実行できます。

# Running as User1
cd /dir1/dir2/dir3/
chmod +r myjar.jar

しかし、それでも機能しません。

# Running as User2
java -cp "/dir1/dir2/dir3:/dir1/dir2/javalibs" MyProgram
Error: Could not find or load main class MyProgram

これは、実行中のユーザー(User2)がdir1、dir2、またはjavalibsまたはdir3にアクセスできないためです。User1がファイルを見ることができて、それらにアクセスできるとき、それは誰かを狂わせるかもしれません、しかしエラーはまだUser2のために起こります。


2

mvn eclipse:eclipse これを実行した後、このエラーが発生しましたこれは.classpathファイルを少し台無しにしました。

.classpathからの行を変更する必要がありました

<classpathentry kind="src" path="src/main/java" including="**/*.java"/>
<classpathentry kind="src" path="src/main/resources" excluding="**/*.java"/>

<classpathentry kind="src" path="src/main/java" output="target/classes" />
<classpathentry kind="src" path="src/main/resources" excluding="**"  output="target/classes" />

2

ここに記載されている解決策ではこの問題を解決できませんでした(ただし、記載されている回答で間違いなく私の概念はクリアされました)。私はこの問題に2回直面し、そのたびに(Eclipse IDEで)さまざまなソリューションを試しました。

  • まず、mainプロジェクトのさまざまなクラスで複数のメソッドに遭遇しました。そのため、main後続のクラスからメソッドを削除しました。
  • 次に、私は次の解決策を試しました:
    1. メインプロジェクトディレクトリを右クリックします。
    2. ソースに移動し、クリーンアップして、デフォルトの設定をそのままにし、[完了]をクリックします。バックグラウンドタスクが完了すると、メインプロジェクトディレクトリに移動します。
    3. その後、プロジェクトを閉じて再度開き、ブームを起こしてようやく問題を解決しました。

1
mainメソッドを削除しても問題は解決しません。複数のエントリポイントを持つアプリケーションに技術的に問題はありません。
スティーブンC
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.