Unterschiede zwischen "java -cp" und "java -jar"?

118

Was ist der Unterschied zwischen dem Ausführen einer Java-Anwendung mit
java -cp CLASSPATHund java -jar JAR_FILE_PATH? Wird einer von ihnen dem anderen vorgezogen, um eine Java-Anwendung auszuführen? Ich meine, welche dieser Möglichkeiten ist für JVM teurer (je nach Nutzung der Maschinenressourcen)?

Welches führt dazu, dass JVM beim Ausführen der Anwendung mehr Threads erzeugt?

Reza
quelle

Antworten:

97

Ich bevorzuge die erste Version, um eine Java-Anwendung zu starten, nur weil sie weniger Fallstricke hat ("Willkommen in der Klassenpfad-Hölle"). Die zweite erfordert eine ausführbare JAR-Datei und der Klassenpfad für diese Anwendung muss im Manifest der JAR definiert werden (alle anderen Klassenpfaddeklarationen werden stillschweigend ignoriert ...). Bei der zweiten Version müssten Sie also in die JAR-Datei schauen, das Manifest lesen und herausfinden, ob die Klassenpfadeinträge dort gültig sind, wo die JAR-Datei gespeichert ist ... Das ist vermeidbar.

Ich erwarte für beide Versionen keine Leistungsvorteile oder -nachteile. Es sagt dem JVM nur, welche Klasse für den Hauptthread verwendet werden soll und wo sich die Bibliotheken befinden.

Andreas Dolk
quelle
Was ist mit den Threads? Sind sie hinsichtlich der Anzahl der Threads, die JVM beim Ausführen der Anwendung erzeugt, gleich?
Reza
1
Ja. Beide Versionen suchen die Hauptmethode und führen diese mit einem einzigen Thread aus. Die erste Version übergibt den Klassennamen als Argument, die zweite Version findet der JVM im Hauptfest.
Andreas Dolk
@Andreas_D Bitte schauen Sie sich diesen Beitrag an . Ich denke, ich verwende -cp falsch und kann meinen Fehler nicht korrigieren.
Fu DL
60

Mit dem -cpArgument geben Sie den Klassenpfad an, dh die Pfade zu zusätzlichen Klassen oder Bibliotheken, die Ihr Programm möglicherweise beim Kompilieren oder Ausführen benötigt. Mit geben -jarSie die ausführbare JAR-Datei an, die Sie ausführen möchten.

Sie können nicht beide angeben. Wenn Sie versuchen zu laufen java -cp folder/myexternallibrary.jar -jar myprogram.jar, wird es nicht wirklich funktionieren. Der Klassenpfad für diese JAR sollte in ihrem Manifest angegeben werden, nicht als -cpArgument.

Mehr dazu finden Sie hier und hier .

PS: -cpund -classpathsind Synonyme.

Radu Murzea
quelle
Mein Anliegen ist über die Ressourcen? Gibt es einen Unterschied zwischen den von ihnen verwendeten Ressourcen?
Reza
@Hesam Wenn Sie nach den Leistungsunterschieden zwischen -cpund fragen -classpath, gibt es keinen Unterschied.
Radu Murzea
1
Nein! Ich meinte den Leistungsunterschied zwischen -cp (oder -classpath) und -jar
Reza
2
@Hesam Geben -jarSie an, welche ausführbare JAR Sie ausführen möchten. Geben -cpSie dabei die Pfade zu zusätzlichen Klassen / Bibliotheken an, die Ihr Programm möglicherweise benötigt. Die 2 haben sehr unterschiedliche Zwecke.
Radu Murzea
@ RaduMurzea, was meinst du damit, dass es nicht wirklich funktionieren würde, wenn wir sie kombinieren? ZBjava -jar PATH -cp PATH2
Pacerier
18

Bei der Verwendung müssen java -cpSie einen vollständig qualifizierten Hauptklassennamen angeben, z

java -cp com.mycompany.MyMain

Bei Verwendung java -jar myjar.jarIhrer JAR-Datei müssen die Informationen zur Hauptklasse über manifest.mf bereitgestellt werden, die in der JAR-Datei im Ordner enthalten sind META-INF:

Main-Class: com.mycompany.MyMain

AlexR
quelle
Bitte schauen Sie sich diesen Beitrag an . Ich glaube, ich verwende -cp falsch und kann meinen Fehler nicht korrigieren.
Fu DL
10

java -cp CLASSPATH ist erforderlich, wenn Sie den gesamten Code im Klassenpfad angeben möchten. Dies ist nützlich zum Debuggen von Code.

Das jarred ausführbare Format: java -jar JarFilekann verwendet werden, wenn Sie die App mit einem einzigen kurzen Befehl starten möchten. Sie können zusätzliche abhängige JAR-Dateien in Ihrem MANIFEST angeben, indem Sie in einem Klassenpfadeintrag durch Leerzeichen getrennte JAR-Dateien verwenden, z.

Class-Path: mysql.jar infobus.jar acme/beans.jar

Beide sind hinsichtlich der Leistung vergleichbar.

Reimeus
quelle
Bitte schauen Sie sich diesen Beitrag an . Ich glaube, ich verwende -cp falsch und kann meinen Fehler nicht korrigieren.
Fu DL
2

Wie bereits gesagt, dient -cp nur dazu, der JVM in der Befehlszeile mitzuteilen, welche Klasse für den Hauptthread verwendet werden soll und wo sie die Bibliotheken finden kann (Klassenpfad definieren). In -jar wird erwartet, dass der Klassenpfad und die Hauptklasse im Manifest der JAR-Datei definiert werden. Andere dienen dazu, Dinge in der Befehlszeile zu definieren, während andere sie im JAR-Manifest finden. Es gibt keinen Unterschied in der Leistung. Sie können sie nicht gleichzeitig verwenden, -jar überschreibt -cp.

Auch wenn Sie -cp verwenden, wird die Manifestdatei überprüft. Sie können also einige der Klassenpfade im Manifest und einige in der Befehlszeile definieren. Dies ist besonders nützlich, wenn Sie von einem JAR eines Drittanbieters abhängig sind, das Sie möglicherweise nicht mit Ihrem Build bereitstellen oder nicht bereitstellen möchten (vorausgesetzt, es befindet sich bereits in dem System, auf dem es beispielsweise installiert werden soll). Sie können es also verwenden, um externe Gläser bereitzustellen. Der Standort kann zwischen den Systemen variieren oder es kann sogar eine andere Version auf einem anderen System vorhanden sein (jedoch mit denselben Schnittstellen). Auf diese Weise können Sie die App mit einer anderen Version erstellen und die tatsächliche Abhängigkeit von Drittanbietern zum Klassenpfad in der Befehlszeile hinzufügen, wenn Sie sie auf verschiedenen Systemen ausführen.

Pehmolelu
quelle
1

Es wird keinen Unterschied in Bezug auf die Leistung geben. Mit java - cp können wir die erforderlichen Klassen und Jars im Klassenpfad angeben, um eine Java-Klassendatei auszuführen.

Wenn es sich um eine ausführbare JAR-Datei handelt. Wenn der Befehl java -jar verwendet wird, findet jvm die Klasse, die ausgeführt werden muss, aus der Datei /META-INF/MANIFEST.MF in der JAR-Datei.

Ravi Sankar Reddy
quelle