回答:
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[])
String[]
ます。「メインクラスを見つけられなかったか、ロードできませんでした...」というメッセージが表示された場合、それは最初のステップが失敗したことを意味します。java
コマンドは、クラスを見つけることができませんでした。そして実際、「...」のメッセージになります完全修飾クラス名java
を募集しています。
では、なぜクラスを見つけられないのでしょうか?
最初の原因として、間違ったクラス名を指定した可能性があります。(または...正しいクラス名ですが、形式が間違っています。)上記の例を考慮して、クラス名を指定するさまざまな間違った方法を次に示します。
例#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番目に考えられる原因は、クラス名は正しいが、java
コマンドがクラスを見つけられないことです。これを理解するには、「クラスパス」の概念を理解する必要があります。これはOracleのドキュメントでよく説明されています。
java
コマンドのドキュメントしたがって、クラス名を正しく指定した場合、次にチェックすることは、クラスパスを正しく指定したことです。
java
コマンドを実行したときに有効なCLASSPATH環境変数を確認します。ディレクトリー名とJARファイル名が正しいことを確認してください。java
コマンドを実行したときに有効な現在のディレクトリから。;
Windowsと:
その他にあります。プラットフォームで間違ったセパレーターを使用すると、明示的なエラーメッセージは表示されません。代わりに、存在しないファイルまたはディレクトリがパス上に表示され、暗黙的に無視されます。 。)クラスパスにディレクトリを置くと、それは概念的には修飾された名前空間のルートに対応します。クラスは、完全修飾名をパス名にマッピングすることにより、そのルートの下のディレクトリ構造に配置されます。たとえば、「/ 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はクラスを見つけることができません。
クラスの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
そして上のようにします。クラスパスには、アプリケーションが依存する他のすべての(非システム)クラスを含める必要があります。(システムクラスは自動的に配置されるため、これを気にする必要はほとんどありません。)メインクラスが正しくロードされるためには、JVMは以下を見つける必要があります。
(注:JLSおよびJVM仕様では、JVMがクラスを「遅延して」ロードするためのスコープが許可されており、これはクラスローダー例外がスローされたときに影響する可能性があります。)
誰かがソースコードファイルをソースコードツリーの間違ったフォルダに配置したり、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リリースのコマンドの公式ドキュメントを参照してください。
典型的なJava IDEは、IDE JVM自体または子JVMでのJavaアプリケーションの実行をサポートしています。IDEは独自のメカニズムを使用してランタイムクラスパスを構築し、メインクラスを識別してコマンドラインを作成するため、これらは通常、この特定の例外の影響を受けませんjava
。
ただし、IDEの背後で何かを行うと、この例外が発生する可能性があります。たとえば、以前にEclipseでJavaアプリのアプリケーションランチャーを設定していて、「メイン」クラスを含むJARファイルをEclipseに通知せずにファイルシステムの別の場所に移動した場合、Eclipseは意図せずにJVMを起動しますクラスパスが正しくありません。
つまり、IDEでこの問題が発生した場合は、古いIDEの状態、壊れたプロジェクト参照、壊れたランチャー構成などを確認してください。
IDEが単に混乱する可能性もあります。IDEは非常に複雑なソフトウェアであり、相互作用する多くの部分で構成されています。これらのパーツの多くは、IDE全体を応答可能にするために、さまざまなキャッシュ戦略を採用しています。これらは時々失敗する可能性があり、1つの考えられる症状は、アプリケーションの起動時の問題です。これが発生していると思われる場合は、IDEの再起動、プロジェクトの再ビルドなど、他のことを試す価値があります。
java -cp ../third-party-library.jar com.my.package.MyClass
; これは機能しません。代わりに、ローカルフォルダーもクラスパスに追加する必要があります(次の:
ようにで区切られます:java -cp ../third-party-library.jar:. com.my.package.MyClass
、それから機能するはずです
java
インポートされたクラスが見つからないというのではなく、実行しようとしているメインクラスが表示されないのは残念です。これには誤解がありますが、その理由は確かです。java
私のクラスがどこにあるかを正確に知っているケースがありましたが、インポートされたクラスの1つを見つけることができませんでした。それを言う代わりに、それは私のメインクラスを見つけられないことについて不平を言いました。本当に、うんざり。
ソースコード名がHelloWorld.javaの場合、コンパイルされたコードはになりますHelloWorld.class
。
次を使用して呼び出すと、そのエラーが発生します。
java HelloWorld.class
代わりに、これを使用してください:
java HelloWorld
javac TestCode.java
行いました。続いてjava TestCode
java -classpath . HelloWorld
クラスがパッケージ内にある場合はcd
、プロジェクトのルートディレクトリに移動し、クラスの完全修飾名(packageName.MainClassName)を使用して実行する必要があります。
例:
私のクラスはここにあります:
D:\project\com\cse\
私のメインクラスの完全修飾名は次のとおりです。
com.cse.Main
cd
ルートプロジェクトディレクトリに戻ります。
D:\project
次に、java
コマンドを発行します。
java com.cse.Main
この回答は、よくある間違いによって引き起こされるフラストレーションから初心者のJavaプログラマーを救うためのものです。Javaクラスパスについての詳細な知識については、受け入れられた回答を読むことをお勧めします。
メインクラスとメインメソッドをで定義する場合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台のPCで機能しても、別のPCでエラーが表示される場合、私が見つけた最良の解決策は、次のようにコンパイルすることです。
javac HelloWorld.java
java -cp . HelloWorld
javac -classpath . HelloWorld.java
でしょう!そして、それはあなたの場合にはより良い解決策です。
たとえば、コマンドラインでクラスパスを指定するのに役立ちました。
新しいフォルダを作成し、 C:\temp
C:\temp
次のクラスを含むTemp.javaファイルをで作成します。
public class Temp {
public static void main(String args[]) {
System.out.println(args[0]);
}
}
folder C:\temp
でコマンドラインを開き、次のコマンドを記述してTempクラスをコンパイルします。
javac Temp.java
コンパイルされたJavaクラスを実行し、クラスの-classpath
場所をJREに知らせるオプションを追加します。
java -classpath C:\temp Temp Hello!
java
使用すると、クラスパスの設定はありませんでした環境で設定されていなかった-classpathまたは-jar)または2)を使用しているため($ CLASSPATHを見ていていなかった効果でコンテキストでjava
いました実行; たとえば、正しいシェルにsetenvコマンドを追加したファイルを「ソース」しなかったためです。
エラーメッセージ(「メインクラスが見つからないか、ロードできませんでした」)によると、問題には次の2つのカテゴリがあります。
メインクラスがすることができませんでしたがあるときにタイプミスや間違った構文が完全修飾クラス名にまたはそれが提供するクラスパスに存在しません。
クラスを開始できないときにメインクラスをロードできませんでした。通常、メインクラスは別のクラスを拡張し、そのクラスは提供されたクラスパスに存在しません。
例えば:
public class YourMain extends org.apache.camel.spring.Main
camel-springが含まれていない場合、このエラーが報告されます。
extends
)。メインクラスが見つからなかった別のクラスを拡張するためにロードに失敗したときに、java が実際のクラスが見つからなかったことを報告しない(とは異なり)という難しい方法を学んだところです。ですから、そうなります。これを知らないのは、髪を引っ張るような状況です。NoClassDefFoundError
-Xdiagを試してください。
スティーブCの答えはうまく可能なケースをカバーし、時にはクラスができなかったかどうかを判断するために見つけるか、ロードされたことは容易ではないかもしれません。使用しますjava -Xdiag
(JDK 7以降)。これは、メッセージCould not find or load main class
メッセージが何を意味するかについてのヒントを提供する素晴らしいスタックトレースを出力します。
たとえば、メインクラスが使用できなかった他のクラスを見つけることができず、メインクラスをロードできなかった可能性があります。
次のコマンドを使用します。
java -cp . [PACKAGE.]CLASSNAME
例:クラス名がHello.javaから作成されたHello.classの場合、次のコマンドを使用します。
java -cp . Hello
Hello.javaファイルがcom.demoパッケージ内にある場合は、次のコマンドを使用します。
java -cp . com.demo.Hello
JDK 8では、クラスファイルが同じフォルダーに存在するjava
ことがよくありますが、コマンドはクラスパスを想定しているため-cp .
、現在のフォルダーをクラスパスの参照として使用するように追加します。
-cp .
は不要です。なぜなら、$CLASSPATH
が設定されていない場合.
は、がデフォルトのクラスパスだからです。
echo %CLASSPATH%
出力されますか?)そして、いいえ、Windows PCを持っていないので確認できません。
時々問題を引き起こしているかもしれないことがメインクラスとは何の関係もない、そして私はこれを難しい方法で見つけなければならなかった。それは私が移動した参照ライブラリであり、それは私に以下を与えました:
メインクラスxxx Linuxを検出またはロードできませんでした
その参照を削除して再度追加したところ、再び正常に機能しました。
私は同じ問題を抱えていて、ついに私の間違いを発見しました:)私はこのコマンドをコンパイルに使用し、正しく機能しました:
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
これは、あなたのケースが特に私の場合に役立つかもしれません。初心者として、Javaプログラムを実行しようとしたときにこの問題にも遭遇しました。
私はそれを次のようにコンパイルしました:
javac HelloWorld.java
そして私は同じ拡張子で実行しようとしました:
java Helloworld.java
を削除しての.java
ようjava HelloWorld
にコマンドを書き換えると、プログラムは完全に実行されました。:)
ここでのすべての回答は、Windowsユーザーを対象としています。Macの場合、クラスパス区切り文字は:
ではなく;
です。使用するクラスパスの設定エラー;
がスローされないため、WindowsからMacに移行する場合、これを見つけるのは困難です。
以下は対応するMacコマンドです。
java -classpath ".:./lib/*" com.test.MyClass
この例では、パッケージがcom.test
あり、lib
フォルダーもクラスパスに含まれます。
/*
必要なのですか?
クラスファイルの場所: C:\ test \ com \ company
ファイル名: Main.class
完全修飾クラス名: com.company.Main
コマンドラインコマンド:
java -classpath "C:\test" com.company.Main
クラスパスには\ com \ companyが含まれていないことに注意してください
私はこの問題を解決するためにかなりの時間を費やしました。私はどういうわけかクラスパスを間違って設定していると思いましたが、問題は入力したことでした:
java -cp C:/java/MyClasses C:/java/MyClasses/utilities/myapp/Cool
の代わりに:
java -cp C:/java/MyClasses utilities/myapp/Cool
完全修飾の意味は、完全なパッケージ名の代わりに完全なパス名を含めることだと思いました。
utilities.myapp.Cool
は、そのパッケージ名が存在する場合は、その名前を指定する必要があります。
まず、このコマンドを使用してパスを設定します。
set path="paste the set path address"
次に、プログラムをロードする必要があります。保存したドライブに「cd(フォルダ名)」と入力してコンパイルします。たとえば、プログラムがDドライブに保存されている場合は、「D:」と入力してEnterキーを押し、「cd(フォルダ名)」と入力します。
if "cd" helps then it by luck rather than by judgement
。javaは.
デフォルトで現在のディレクトリをクラスパスの一部として使用するため、これは誤りです(私は信じています)。
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>
Windowsでは.;
、最初にCLASSPATH値を指定します。
。(ドット)は、「現在のディレクトリを探す」ことを意味します。これは永続的な解決策です。
また、setで「1回」に設定することもできますCLASSPATH=%CLASSPATH%;.
。これは、cmdウィンドウが開いている限り続きます。
これは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
cd
しsrc
てから実行するjava ../bin com.blah.blah.MyClass
必要がありました。先端をありがとう!
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/
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がクラスパス引数を正しく処理できるようになります。
Java MongoDB JDBC接続のテスト中にも、同様のエラーに直面しました。私の最終的な解決策を要約すると、将来的に誰もが2つのコマンドを直接調べることができ、さらに先に進むことができるようになるので、良いと思います。
Javaファイルと外部依存関係(JARファイル)が存在するディレクトリにいるとします。
コンパイル:
javac -cp mongo-java-driver-3.4.1.jar JavaMongoDBConnection.java
実行:
java -cp mongo-java-driver-3.4.1.jar: JavaMongoDBConnection
JavaMongoDBConnection
パッケージがないこと、2)ディレクトリを変更しないことを前提としています。控えめに言っても、それは壊れやすいです。そして、問題を説明しないことで、初心者はそれが機能しない状況でこのアプローチを試すようになります。つまり、「ブードゥープログラミングテクニック」を奨励します。en.wikipedia.org
大丈夫、すでに多くの答えがありますが、ファイルのアクセス許可が犯人になる可能性があるケースについて誰も言及しませんでした。
実行中、ユーザーは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のために起こります。
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回直面し、そのたびに(Eclipse IDEで)さまざまなソリューションを試しました。
main
プロジェクトのさまざまなクラスで複数のメソッドに遭遇しました。そのため、main
後続のクラスからメソッドを削除しました。main
メソッドを削除しても問題は解決しません。複数のエントリポイントを持つアプリケーションに技術的に問題はありません。