Führen Sie eine JAR-Datei über die Befehlszeile aus und geben Sie den Klassenpfad an

115

Ich habe eine JAR- Datei kompiliert und die Hauptklasse im Manifest angegeben (ich habe die Eclipse- Exportfunktion verwendet). Meine Abhängigkeiten befinden sich alle in einem Verzeichnis mit der Bezeichnung lib. Ich kann anscheinend keine eindeutige Antwort darauf erhalten, wie meine JAR-Datei ausgeführt wird, während angegeben wird, dass die lib/*als Klassenpfad verwendet werden soll.

Ich habe es versucht:

]$ java -jar -cp .:lib/* MyJar.jar
]$ java -cp .:lib/* -jar MyJar.jar
]$ java -cp .:lib/* com.somepackage.subpackage.Main

etc...

Jeder gibt einen Fehler aus und sagt:

Error: Could not find or load main class ....

oder gibt an, NoClassDefFoundErrordass die Bibliotheken nicht gefunden werden.

Ich habe sogar versucht, die JAR-Datei neu zu erstellen und das libVerzeichnis und den Inhalt eingefügt , aber immer noch keine Würfel ...

Wie kann ich eine JAR-Datei über die Befehlszeile ausführen und den zu verwendenden Klassenpfad angeben?

SnakeDoc
quelle
Mögliches Duplikat der Ausführung der JAR-Datei mit mehreren Klassenpfadbibliotheken an der Eingabeaufforderung
Adam Michalik

Antworten:

203

Wenn Sie angeben, -jarwird der -cpParameter ignoriert.

Aus der Dokumentation :

Wenn Sie diese Option verwenden, ist die JAR-Datei die Quelle aller Benutzerklassen, und andere Benutzerklassenpfadeinstellungen werden ignoriert.

Sie können benötigte JAR-Dateien auch nicht in eine andere JAR-Datei "einschließen" (Sie müssten deren Inhalt extrahieren und die .class-Dateien in Ihre JAR-Datei einfügen).

Sie haben zwei Möglichkeiten:

  1. Fügen Sie alle JAR-Dateien aus dem libVerzeichnis in das Manifest ein (Sie können dort relative Pfade verwenden).
  2. Geben Sie alles ( einschließlich Ihrer JAR) in der Befehlszeile an, indem Sie -cp:
    java -cp MyJar.jar:lib/* com.somepackage.subpackage.Main
ein Pferd ohne Name
quelle
22
;; anstelle von: wenn Sie Windows wie folgt verwenden: java -cp MyJar.jar; lib / * com.somepackage.subpackage.Main
Fehler
Sie können benötigte JAR-Dateien auch nicht in eine andere JAR-Datei "einschließen". Sicher kannst du. Wenn es für den internen Gebrauch bestimmt ist (dh Sie erwarten, dass der Benutzer über technische Kenntnisse usw. verfügt), können Sie einfach fragen, ob Schritt 1 ausgeführt werden soll, bevor Sie versuchen, das JAR auszuführen unzip MyJar.jar lib/*.jar. Dann, wie Sie vorschlagen, können sie laufenjava -cp MyJar.jar:lib/* ...
Roger
3
Das Problem ist, dass es ein häufiger Anwendungsfall ist, ein "All-Inclusive" -Überglas mit einem Verweis auf eine externe serverspezifische Eigenschaftendatei auszuführen. Offensichtlich kein Blocker, aber sicherlich ein weniger ausführlicher Befehl, wenn Sie das -jar verwenden könnten und nicht den Hauptbefehl angeben müssten
Andrew Norman
Ich habe eine Weile gebraucht, um das herauszufinden. Das explizite Laden einer log4j-Datei dauert ungefähr 6 Zeilen. Ein weiterer Java-Fehler, der niemals behoben wird.
Tuntable
1
Beachten Sie, dass der manifestierte Klassenpfad nur zum Laden von JAR-Dateien verwendet werden kann. Es kann beispielsweise nicht zum Nachschlagen von log4j3.xml verwendet werden. Hab mich gut gemacht.
Tuntable
34

Führen Sie eine JAR-Datei aus und geben Sie einen Klassenpfad wie folgt an:

java -cp <jar_name.jar:libs/*> com.test.App

jar_name.jar ist der vollständige Name der JAR, die Sie ausführen möchten

libs/* ist ein Pfad zu Ihren Abhängigkeits-JARs

com.test.Appist der vollständig qualifizierte Name der Klasse aus der JAR, die über die main(String[])Methode verfügt

Das Glas und das abhängige Glas sollten über Ausführungsberechtigungen verfügen.

Sid
quelle
10

Sie können dies in der Unix-Shell tun:

java -cp MyJar.jar:lib/* com.somepackage.subpackage.Main

Sie können dies in Windows Powershell tun:

java -cp "MyJar.jar;lib\*" com.somepackage.subpackage.Main
Teere
quelle
4

Alternativ können Sie das Manifest verwenden, um den Klassenpfad und die Hauptklasse anzugeben, wenn Sie möchten. Sie müssen also -cpdie Hauptklasse nicht verwenden oder angeben. In Ihrem Fall würde es Zeilen wie diese enthalten:

Main-Class: com.test.App
Class-Path: lib/one.jar lib/two.jar

Leider müssen Sie jedes Glas im Manifest buchstabieren (kein Problem, wie Sie es nur einmal tun, und Sie können ein Skript zum Erstellen der Datei oder ein Build-Tool wie ANT oder Maven oder Gradle verwenden). Und die Referenz muss ein relatives oder absolutes Verzeichnis sein, in dem Sie das ausführen java -jar MyJar.jar.

Dann führen Sie es mit aus

java -jar MyJar.jar
HankCa
quelle
Ich denke, der Klassenpfad muss sich auf Dateien im äußeren Glas beziehen. Ich konnte dies im Allgemeinen nicht zum Laufen bringen, um auf Konfigurationsdateien außerhalb von MyJar.jar zu verweisen.
Tuntable
0

Sie können einen Befehl Runtime.getRuntime.exec (Befehl) ausführen, um das JAR einschließlich des Klassenpfads mit Argumenten neu zu starten.

Tim de Vries
quelle