Frage Einschließen aller Jars in ein Verzeichnis innerhalb des Java-Klassenpfads


Gibt es eine Möglichkeit, alle JAR-Dateien in ein Verzeichnis im Klassenpfad aufzunehmen?

Ich versuche java -classpath lib/*.jar:. my.package.Program und es ist nicht in der Lage, Klassendateien zu finden, die sicherlich in diesen Gläsern sind. Muss ich jede JAR-Datei separat zum Klassenpfad hinzufügen?


844
2017-10-20 19:32


Ursprung


Antworten:


Mit Java 6 oder höher unterstützt die Klassenpfad-Option Platzhalter. Beachte das Folgende:

  • Verwenden Sie gerade Zitate (")
  • Benutzen *nicht *.jar

Windows

java -cp "Test.jar;lib/*" my.package.MainClass

Unix

java -cp "Test.jar:lib/*" my.package.MainClass

Dies ist ähnlich zu Windows, wird aber verwendet : Anstatt von ;. Wenn Sie keine Platzhalter verwenden können, bash erlaubt die folgende Syntax (wo lib ist das Verzeichnis, das alle Java-Archivdateien enthält):

java -cp $(echo lib/*.jar | tr ' ' ':')

(Beachten Sie, dass die Verwendung eines Klassenpfads nicht kompatibel mit dem ist -jar Möglichkeit. Siehe auch: Führen Sie JAR-Datei mit mehreren Klassenpfadbibliotheken über die Eingabeaufforderung aus)

Wildcards verstehen

Von dem Klassenpfad Dokument:

Klassenpfadeinträge können das Platzhalterzeichen für den Basisnamen enthalten *Dies entspricht einer Liste aller Dateien   in dem Verzeichnis mit der Erweiterung .jar oder .JAR. Zum Beispiel, die   Klassenpfadeintrag foo/* Gibt alle JAR-Dateien im angegebenen Verzeichnis an   foo. Ein Klassenpfadeintrag, der einfach aus * expandiert zu einer Liste von allen   die JAR-Dateien im aktuellen Verzeichnis.

Ein Klassenpfadeintrag, der enthält * passt nicht zu Klassendateien. Zu   Passen Sie sowohl Klassen als auch JAR-Dateien in einem einzigen Verzeichnis foo an, verwenden Sie beides    foo;foo/* oder foo/*;foo. Die gewählte Reihenfolge bestimmt, ob der   Klassen und Ressourcen in foo werden vor JAR-Dateien geladen foo, oder   und umgekehrt.

Unterverzeichnisse werden nicht rekursiv durchsucht. Beispielsweise, foo/* sieht aus   nur für JAR-Dateien in foo, nicht in foo/bar, foo/baz, etc.

Die Reihenfolge, in der die JAR-Dateien in einem Verzeichnis aufgelistet werden   Der erweiterte Klassenpfad ist nicht angegeben und kann von Plattform zu Plattform variieren   Plattform und sogar von Moment zu Moment auf der gleichen Maschine. EIN   Gut konstruierte Anwendung sollte nicht von bestimmten abhängen   Auftrag. Wenn eine bestimmte Reihenfolge erforderlich ist, können die JAR-Dateien sein   explizit im Klassenpfad aufgezählt.

Die Erweiterung von Platzhaltern erfolgt früh vor dem Aufruf von a   die Hauptmethode des Programms, und nicht erst spät während des Ladens der Klasse   Prozess selbst. Jedes Element des Eingabeklassenpfads enthält a   Wildcard wird durch die (möglicherweise leere) Sequenz von Elementen ersetzt   generiert durch Aufzählung der JAR-Dateien im angegebenen Verzeichnis. Zum   Beispiel, wenn das Verzeichnis foo enthält a.jar, b.jar, und c.jar, dann   der Klassenpfad foo/* ist erweitert in foo/a.jar;foo/b.jar;foo/c.jar,   und diese Zeichenfolge wäre der Wert der Systemeigenschaft    java.class.path.

Das CLASSPATH Umgebungsvariable wird nicht anders behandelt als   das -classpath (oder -cp) Befehlszeilenoption. Das heißt, Platzhalter sind   in all diesen Fällen geehrt. Klassenpfad-Platzhalter sind dies jedoch nicht   geehrt in der Class-Path jar-manifestHeader.

Hinweis: Aufgrund eines bekannten Fehlers in Java 8 müssen die Windows-Beispiele einen umgekehrten Schrägstrich vorausgehenden Einträge mit einem nachgestellten Sternchen verwenden: https://bugs.openjdk.java.net/browse/JDK-8131329


976
2017-10-20 20:32



Unter Windows funktioniert das:

java -cp "Test.jar;lib/*" my.package.MainClass

und das funktioniert nicht:

java -cp "Test.jar;lib/*.jar" my.package.MainClass

bemerke das * .jar, Daher sollte der * Platzhalter allein verwendet werden.


Unter Linux funktioniert Folgendes:

java -cp "Test.jar:lib/*" my.package.MainClass

Die Trennzeichen sind Doppelpunkte anstelle von Semikolons.


199
2017-08-14 00:42



Wir umgehen dieses Problem, indem wir ein Main JAR-Datei myapp.jar welches enthält a Manifest (Manifest.mf) Datei, die einen Klassenpfad mit den anderen erforderlichen JARs angibt, die dann zusammen mit diesem bereitgestellt werden. In diesem Fall müssen Sie nur deklarieren java -jar myapp.jar wenn der Code ausgeführt wird.

Also, wenn Sie das Haupt bereitstellen jar in irgendein Verzeichnis und dann die abhängigen Gläser in a lib Ordner darunter, sieht das Manifest wie folgt aus:

Manifest-Version: 1.0
Implementation-Title: myapp
Implementation-Version: 1.0.1
Class-Path: lib/dep1.jar lib/dep2.jar

Hinweis: Dies ist plattformunabhängig - wir können die gleichen Jars verwenden, um auf einem UNIX-Server oder einem Windows-PC zu starten.


59
2017-10-20 20:08



Meine Lösung auf Ubuntu 10.04 mit java-sun 1.6.0_24 mit allen jars im "lib" -Verzeichnis:

java -cp.: lib / * meine.main.Klasse

Wenn dies fehlschlägt, sollte der folgende Befehl funktionieren (druckt alle * .jars im lib-Verzeichnis auf den Classpath-Parameter aus)

java -cp $ (für i in lib / *. jar; mach echo -n $ i:; fertig). meine.main.Klasse

36
2018-03-17 10:55



Kurze Antwort: java -classpath lib/*:. my.package.Program

Oracle bietet eine Dokumentation zur Verwendung von Platzhaltern in Klassenpfaden hier für Java 6 und hier für Java 7, unter der Abschnittsüberschrift Die Platzhalter für Klassenpfade verstehen. (Während ich dies schreibe, enthalten die beiden Seiten die gleichen Informationen.) Hier eine Zusammenfassung der Highlights:

  • Um alle JARs in ein bestimmtes Verzeichnis aufzunehmen, können Sie den Platzhalter verwenden * (nicht  *.jar).

  • Der Platzhalter passt nur zu JARs, nicht zu Klassendateien. Um alle Klassen in einem Verzeichnis abzurufen, beenden Sie einfach den Klassenpfadeintrag unter dem Verzeichnisnamen.

  • Die obigen zwei Optionen können kombiniert werden, um alle JAR- und Klassendateien in einem Verzeichnis zu enthalten, und die üblichen Klassenpfad-Vorrangregeln gelten. Z.B. -cp /classes;/jars/*

  • Der Platzhalter wird nicht Suche nach JARs in Unterverzeichnissen.

  • Die obigen Aufzählungspunkte sind wahr, wenn Sie die CLASSPATH Systemeigenschaft oder der -cp oder -classpath Befehlszeilenflags Wenn Sie jedoch die Class-Path JAR-Manifest-Header (wie Sie es mit einer Ant-Build-Datei tun können), werden Wildcards nicht geehrt werden.

Ja, meine erste Verbindung ist die gleiche, die in der Top-Scoring-Antwort (die ich nicht zu überholen hoffe), aber diese Antwort bietet nicht viel Erklärung über den Link hinaus. Da ist diese Art von Verhalten entmutigt auf Stapelüberlauf heutzutageIch dachte, ich würde es erweitern.


27
2017-12-21 19:32



Für mich funktioniert das in Windows.

java -cp "/lib/*;" sample

Für Linux

java -cp "/lib/*:" sample

ich benutze Java 6


27
2017-10-15 07:43



Sie können Java versuchen -Djava.ext.dirs=jarDirectory http://docs.oracle.com/javase/6/docs/technotes/guides/extensions/spec.html

Verzeichnis für externe Jars, wenn Java ausgeführt wird


21
2018-03-06 21:00



Richtig:

java -classpath "lib/*:." my.package.Program

Falsch:

java -classpath "lib/a*.jar:." my.package.Program
java -classpath "lib/a*:."     my.package.Program
java -classpath "lib/*.jar:."  my.package.Program
java -classpath  lib/*:.       my.package.Program

20
2018-02-13 17:57