Einschließen aller Jars in ein Verzeichnis im Java-Klassenpfad

1019

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

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

Chris Serra
quelle
3
Entschuldigung, ich habe das nie akzeptiert. Es sollte ein Community-Wiki sein. Nie eine der bereitgestellten Antworten verwendet. Ich glaube, ich habe ein Shell-Skript erstellt, das gerade das Verzeichnis lib / gescannt und den Klassenpfad aus dem Parsen von Dateinamen erstellt hat.
Chris Serra
Diese neue Java-Funktion weist einen Fehler auf, da sie nicht wie beschrieben funktioniert. Ich gab auf und benutzte Ant, um es zu umgehen, wie in einer der Antworten beschrieben.
Alex R
1
Es gibt ein Problem mit der Platzhalterverarbeitung in Windows. stackoverflow.com/questions/11607873/…
Mykhaylo Adamovych
6
Kurze Antwort: (1) Löschen Sie das .jarTeil, (2) muss mindestens 2 Teile haben, die unter ;Windows durch ein getrennt sind (was normalerweise :anderswo ist). Zum Beispiel:java -classpath ".;lib/*" Program
Evgeni Sergeev

Antworten:

1160

Bei Verwendung von Java 6 oder höher unterstützt die Option classpath Platzhalter. Beachten Sie das Folgende:

  • Verwenden Sie gerade Anführungszeichen ( ")
  • Verwenden Sie *nicht*.jar

Windows

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

Unix

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

Dies ähnelt Windows, verwendet jedoch :anstelle von ;. Wenn Sie keine Platzhalter verwenden können, bashist die folgende Syntax zulässig (wobei libsich das Verzeichnis mit allen Java-Archivdateien befindet):

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

(Beachten Sie, dass die Verwendung eines Klassenpfads nicht mit der -jarOption kompatibel ist . Siehe auch: JAR-Datei mit mehreren Klassenpfadbibliotheken an der Eingabeaufforderung ausführen. )

Platzhalter verstehen

Aus dem Classpath- Dokument:

Klassenpfadeinträge können das Platzhalterzeichen für den Basisnamen enthalten *, das der Angabe einer Liste aller Dateien im Verzeichnis mit der Erweiterung .jaroder entspricht .JAR. Beispielsweise gibt der Klassenpfadeintrag foo/*alle JAR-Dateien im Verzeichnis mit dem Namen foo an. Ein Klassenpfadeintrag, der einfach *aus besteht, wird zu einer Liste aller JAR-Dateien im aktuellen Verzeichnis erweitert.

Ein Klassenpfadeintrag, der enthält, *stimmt nicht mit Klassendateien überein. Verwenden Sie entweder foo;foo/*oder , um sowohl Klassen als auch JAR-Dateien in einem einzigen Verzeichnis foo abzugleichen foo/*;foo. Die gewählte Reihenfolge bestimmt, ob die Klassen und Ressourcen in foovor JAR-Dateien geladen foowerden oder umgekehrt.

Unterverzeichnisse werden nicht rekursiv durchsucht. Zum Beispiel foo/*sucht nach JAR - Dateien nur in foo, nicht in foo/bar, foo/bazusw.

Die Reihenfolge, in der die JAR-Dateien in einem Verzeichnis im erweiterten Klassenpfad aufgelistet werden, ist nicht angegeben und kann von Plattform zu Plattform und sogar von Moment zu Moment auf demselben Computer variieren. Eine gut konstruierte Anwendung sollte nicht von einer bestimmten Reihenfolge abhängen. Wenn eine bestimmte Reihenfolge erforderlich ist, können die JAR-Dateien explizit im Klassenpfad aufgelistet werden.

Das Erweitern von Platzhaltern erfolgt früh vor dem Aufruf der Hauptmethode eines Programms und nicht erst spät während des Ladevorgangs. Jedes Element des Eingabeklassenpfads, das einen Platzhalter enthält, wird durch die (möglicherweise leere) Folge von Elementen ersetzt, die durch Auflisten der JAR-Dateien im benannten Verzeichnis generiert werden. Wenn das Verzeichnis beispielsweise foo,, und enthält a.jar, b.jarwird c.jarder Klassenpfad foo/*erweitert foo/a.jar;foo/b.jar;foo/c.jar, und diese Zeichenfolge ist der Wert der Systemeigenschaft java.class.path.

Die CLASSPATHUmgebungsvariable wird nicht anders behandelt als die Befehlszeilenoption -classpath(oder -cp). Das heißt, in all diesen Fällen werden Platzhalter berücksichtigt. Platzhalter für Klassenpfade werden im Class-Path jar-manifestHeader jedoch nicht berücksichtigt.

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

Basszero
quelle
2
Die Funktion ist schlecht dokumentiert und scheint zu erfordern, dass einige weniger als offensichtliche Voraussetzungen erfüllt sind, um wie beabsichtigt zu arbeiten.
Alex R
1
+1 für den letzten Bash / Tr-Trick. Java / JamVM mag hier keine Platzhalter für Pfade außerhalb des Arbeitsverzeichnisses, aber das explizite Verweisen auf jede JAR mit Shell Wildcard + trfunktioniert!
Supr
1
Ich habe einen Befehl java -classpath /jars/*:/anotherJarsDir/* com.test.MyClassohne Anführungszeichen und es funktioniert gut. Ich frage mich, warum Shell es nicht erweitert und Fehler macht.
Yellavon
3
Verwenden Sie auch nicht ~in der -cp
Sohail Si
1
Ihr Windows-Beispiel funktioniert nicht mit Java 8 oder früher, würde aber mit diesem Klassenpfad funktionieren: Test.jar; lib \ * ... Schrägstrich ist in Ordnung, außer wenn Sie vor einem Sternchen und einigen anderen stehen ... siehe bugs.openjdk. java.net/browse/JDK-8131329
philwalk
226

Unter Windows funktioniert dies:

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

und das funktioniert nicht:

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

Beachten Sie die * .jar, daher sollte der * Platzhalter alleine verwendet werden .


Unter Linux funktioniert Folgendes:

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

Die Trennzeichen sind Doppelpunkte anstelle von Semikolons.

davorp
quelle
17
Die perfekte Antwort. 2 wichtige Dinge zu beachten: 1) Verwenden Sie Anführungszeichen und 2) Verwenden Sie * nur, nicht * .jar
Wim Deblauwe
4
Ein Jahr und 8 Monate später hat mich die Bearbeitung, die ich vorgenommen habe, um die UNIX-Version aufzunehmen, erneut gerettet. :) Komisch, wie es meine JAR-Dateien nicht erkennen würde, *.jaraber nur mit *.
jmort253
Ich fand, dass die Reihenfolge der Klassenpfade wichtig ist (aber ich weiß nicht warum). Ich bekam Fehler, bis ich die Reihenfolge der Klassenpfade wechselte.
user13107
@ jmort253, die Sache ist, dies ist nicht die Shell *, die sich ausdehnt, aber der Platzhalter ist Java, der den Klassenpfad analysiert, den * sieht und den Platzhalter ausfüllt
Sebastian
1
@SebastianGodelet - Yeh, das ist nur ich, der zwischen Regex-Platzhaltern und dieser Notation verwechselt wird, was nicht dasselbe ist, denke ich. Meistens hat es mich gerettet, den Unterschied zwischen :einer Plattform und ;der anderen zu kennen. :) Ich kompiliere ungefähr einmal im Jahr mit Java über die Kommandozeile, gerade genug, um mich nicht daran zu erinnern, wie oft noch nervig.
jmort253
67

Wir umgehen dieses Problem, indem wir eine Haupt- JAR-Datei bereitstellen, myapp.jardie eine manifest ( Manifest.mf) - Datei enthält, die einen Klassenpfad mit den anderen erforderlichen Jars angibt, die dann daneben bereitgestellt werden. In diesem Fall müssen Sie nur deklarierenjava -jar myapp.jar wenn Sie den Code ausführen.

Wenn Sie also das Hauptmenü jarin einem Verzeichnis bereitstellen und dann die abhängigen Gläser in einen libOrdner darunter legen , sieht das Manifest folgendermaßen aus:

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

NB: Dies ist plattformunabhängig. Wir können dieselben Jars verwenden, um auf einem UNIX-Server oder einem Windows-PC zu starten.

oxbow_lakes
quelle
Dies scheint für viele Leute zu funktionieren, Java scheint jedoch die Klassenpfadeinträge in der Manifestdatei hier eindeutig zu ignorieren. Wir können die Anwendung nicht ausführen, ohne "lib / *" manuell mit -cp zum Klassenpfad hinzuzufügen. Irgendwelche Ideen?
Raku
6
Die Antwort von oxbow_lakes ist nicht ganz richtig. Das Class-Path-Ding wird geehrt (und NUR das wird gewürdigt; -cp / -classpath wird ignoriert!), wenn Sie dieses Glas mit java -jar myapp.jar starten. Ich nehme an, oxbow_lakes wollte das schreiben, als er 'java -classpath myapp.jar' schrieb.
rzwitserloot
47

Meine Lösung unter Ubuntu 10.04 mit Java-Sun 1.6.0_24 mit allen Jars im Verzeichnis "lib":

java -cp .: lib / * my.main.Class

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

java -cp $ (für i in lib / *. jar; echo -n $ i :; done). my.main.Class
Habi
quelle
4
eine lustige Notiz. java -cp lib / * my.main.Class schlägt immer fehl, weil die Shell-Glob-Erweiterung von lib / *, während java -cp .: lib / * my.main.Class nicht, weil .: lib / * kein gültiger Glob ist Pfad. Nehmen Sie sich eine Weile Zeit, um das zu bemerken
Albfan
1
Das funktioniert nicht; Linux wird das erweitern . Sie können versuchen: java -cp '.: lib / ' und das funktioniert gut (beachten Sie die einfachen Anführungszeichen! Es wird nicht mit doppelten Anführungszeichen funktionieren!). Eigentlich könnte.: Lib / * funktionieren, wenn dies aufgrund des Doppelpunkts kein legitimer Glob ist, aber es fühlt sich ein bisschen zweifelhaft an. Ich würde die Anführungszeichen hinzufügen. Die einfachen Anführungszeichen weisen bash an, keinen Teil des Inhalts zu berühren.
Rzwitserloot
Es spielt (in diesem Zusammenhang) keine Rolle, ob Sie einfache oder doppelte Anführungszeichen verwenden. Sie möchten verhindern, dass die Shell das * erweitert (globbing), das ist alles. Übergeben Sie den Text "lib / *" wörtlich an die JVM, damit die VM dies als "spezielles Muster" erkennt und selbst nach JAR-Dateien sucht.
Angel O'Sphere
36

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 Überschrift Grundlegende Platzhalter für Klassenpfade . (Während ich dies schreibe, enthalten die beiden Seiten die gleichen Informationen.) Hier ist eine Zusammenfassung der Highlights:

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

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

  • Die beiden oben genannten Optionen können kombiniert werden, um alle JAR- und Klassendateien in ein Verzeichnis aufzunehmen, und es gelten die üblichen Regeln für die Priorität von Klassenpfaden. Z.B-cp /classes;/jars/*

  • Der Platzhalter sucht nicht nach JARs in Unterverzeichnissen.

  • Die obigen Aufzählungspunkte sind wahr, wenn Sie die CLASSPATHSystemeigenschaft oder die Befehlszeilenflags -cpoder verwenden -classpath. Wenn Sie jedoch den Class-PathJAR-Manifest-Header verwenden (wie dies bei einer Ant-Build-Datei der Fall ist ), werden Platzhalter nicht berücksichtigt.

Ja, mein erster Link ist derselbe, der in der Antwort mit der höchsten Punktzahl angegeben ist (von der ich keine Hoffnung habe, sie zu überholen), aber diese Antwort bietet nicht viel Erklärung über den Link hinaus. Da diese Art von Verhalten entmutigt auf Stack - Überlauf in diesen Tagen , dachte ich , dass ich auf diese erweitern würde.

Pops
quelle
Mein Problem war eher mit lib / *. jar als mit lib / *. Vielen Dank, das hat es behoben. Mir ist aufgefallen, dass es einen Unterschied gibt zwischen: und; Aber das könnte meine Art sein, viele Änderungen gleichzeitig zu testen.
Eyad Ebrahim
Vielen Dank für die Betonung des Unterschieds zwischen * und * .jar
burakhan alkan
36

Windows :

 java -cp file.jar;dir/* my.app.ClassName

Linux :

 java -cp file.jar:dir/* my.app.ClassName

Denken Sie daran:
- Windows- Pfadtrennzeichen ist ;
- Linux- Pfadtrennzeichen ist :
- In Windows ist das "Anführungszeichen" optional, wenn das cp-Argument keinen Leerraum enthält

Wender
quelle
Windows-Beispiel funktioniert nicht für Java 8 und früher: siehe bugs.openjdk.java.net/browse/JDK-8131329
Philwalk
Vielleicht funktioniert nicht für Open JDK, ich werde dies testen und ich werde hier darüber sprechen
Wender
Entschuldigung, ich habe mit HotSpot getestet und dachte, dass das mit openjdk funktioniert.
Wender
Oracle Java unter Windows erfordert einen Backslash vor dem Sternchen anstelle eines Schrägstrichs, obwohl ich die neuesten oder alternativen Java-Versionen nicht erneut getestet habe.
Philwalk
funktioniert nicht auf
Macos
34

Bei mir funktioniert das in Windows.

java -cp "/lib/*;" sample

Für Linux

java -cp "/lib/*:" sample

Ich benutze Java 6

SANN3
quelle
Windows-Beispiel scheint für Java 6 funktioniert zu haben, vielleicht Java 7, aber nicht für Java 8 (siehe bugs.openjdk.java.net/browse/JDK-8131329 )
Philwalk
Funktioniert für Java 8 unter Linux
Jonathan Drapeau
29

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

Verzeichnis für externe Jars beim Ausführen von Java

Navi
quelle
3
Dies funktioniert, aber aufgepasst, passieren Sie die -Djava.ext.dirs=VOR-jar
Giovanni Funchal
5
java.ext.dirs funktioniert ganz anders als ein normales Glas im Klassenpfad. Es hat eine höhere Priorität und Berechtigung, die Klassen im Bootstamp (rt.jar) irgendwie überschreiben können
Dennis C
Vielen Dank. In 'Java-Version "1.8.0_221" Java (TM) SE-Laufzeitumgebung (Build 1.8.0_221-b27) Java HotSpot (TM) 64-Bit-Server-VM (Build 25.221-b27, gemischter Modus)' nur diese -D-Version im Klassenpfad vorbeizukommen hat funktioniert. Die traditionelle Form tat es nicht.
Matt Campbell
23

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
Rvernica
quelle
9

Wenn Sie wirklich alle JAR-Dateien dynamisch angeben müssen, können Sie Shell-Skripte oder Apache Ant verwenden . Es gibt ein Commons-Projekt namens Commons Launcher, mit dem Sie Ihr Startskript im Grunde genommen als Ant-Build-Datei angeben können (wenn Sie sehen, was ich meine).

Dann können Sie Folgendes angeben:

<path id="base.class.path">
    <pathelement path="${resources.dir}"/>
    <fileset dir="${extensions.dir}" includes="*.jar" />
    <fileset dir="${lib.dir}" includes="*.jar"/>
</path>

In Ihrer Start-Build-Datei, die Ihre Anwendung mit dem richtigen Klassenpfad startet.


quelle
8

Bitte beachten Sie, dass die Platzhaltererweiterung für Java 7 unter Windows nicht funktioniert.

Weitere Informationen finden Sie in diesem StackOverflow-Problem .

Die Problemumgehung besteht darin, ein Semikolon direkt nach dem Platzhalter einzufügen. java -cp "somewhere/*;"

Jake Toronto
quelle
6

Wen es angeht,

Ich fand dieses seltsame Verhalten unter Windows unter einer MSYS / MinGW-Shell.

Werke:

$ javac -cp '.;c:\Programs\COMSOL44\plugins\*' Reclaim.java

Funktioniert nicht:

$ javac -cp 'c:\Programs\COMSOL44\plugins\*' Reclaim.java
javac: invalid flag: c:\Programs\COMSOL44\plugins\com.comsol.aco_1.0.0.jar
Usage: javac <options> <source files>
use -help for a list of possible options

Ich bin mir ziemlich sicher, dass der Platzhalter nicht durch die Shell erweitert wird, weil z

$ echo './*'
./*

(Versuchte es auch mit einem anderen Programm anstatt mit dem eingebauten echo, mit dem gleichen Ergebnis.)

Ich glaube, es ist das, javacwas versucht, es zu erweitern, und es verhält sich anders, ob das Argument ein Semikolon enthält oder nicht. Erstens wird möglicherweise versucht, alle Argumente zu erweitern, die wie Pfade aussehen. Und nur dann würde es sie analysieren -cpund nur das folgende Zeichen nehmen. (Beachten Sie, dass dies com.comsol.aco_1.0.0.jardie zweite JAR in diesem Verzeichnis ist.) Das ist alles eine Vermutung.

Das ist

$ javac -version
javac 1.7.0
Evgeni Sergeev
quelle
5

Alle oben genannten Lösungen funktionieren hervorragend, wenn Sie die Java-Anwendung außerhalb einer IDE wie Eclipse oder Netbeans entwickeln und ausführen.

Wenn Sie unter Windows 7 arbeiten und Eclipse IDE für die Entwicklung in Java verwenden, können Probleme auftreten, wenn Sie die in Eclipse erstellten Klassendateien mithilfe der Eingabeaufforderung ausführen.

Beispiel: Ihr Quellcode in Eclipse weist die folgende Pakethierarchie auf: edu.sjsu.myapp.Main.java

Sie haben json.jar als externe Abhängigkeit für Main.java

Wenn Sie versuchen, Main.java in Eclipse auszuführen, wird es ohne Probleme ausgeführt.

Wenn Sie jedoch versuchen, dies mit der Eingabeaufforderung auszuführen, nachdem Sie Main.java in Eclipse kompiliert haben, werden einige seltsame Fehler mit der Meldung "ClassNotDef Error blah blah" angezeigt.

Ich gehe davon aus, dass Sie sich im Arbeitsverzeichnis Ihres Quellcodes befinden !!

Verwenden Sie die folgende Syntax, um es an der Eingabeaufforderung auszuführen:

  1. javac -cp ".; json.jar" Main.java

  2. java -cp ".; json.jar" edu.sjsu.myapp.Main

    [Verpassen Sie nicht die. über]

Dies liegt daran, dass Sie die Datei Main.java im Paket edu.sjsu.myapp platziert haben und java.exe nach dem genauen Muster sucht.

Ich hoffe es hilft !!

realPK
quelle
4

Für Windows sind Anführungszeichen erforderlich und; sollte als Trennzeichen verwendet werden. z.B:

java -cp "target\\*;target\\dependency\\*" my.package.Main
Alexey
quelle
4

Kurzform: Wenn sich Ihr Main in einem JAR befindet, benötigen Sie wahrscheinlich einen zusätzlichen '-jar pathTo / yourJar / YourJarsName.jar', der explizit deklariert wurde, damit es funktioniert (obwohl sich 'YourJarsName.jar' im Klassenpfad befand) (oder , ausgedrückt, um die ursprüngliche Frage zu beantworten, die vor 5 Jahren gestellt wurde: Sie müssen nicht jedes Glas explizit neu deklarieren, aber es scheint, dass Sie selbst mit Java6 Ihr eigenes Glas neu deklarieren müssen ...)


Lange Form: (Ich habe dies so deutlich gemacht, dass ich hoffe, dass auch Eindringlinge von Java davon Gebrauch machen können.)

Wie viele hier verwende ich Eclipse zum Exportieren von Jars: (Datei-> Exportieren -> 'Runnable JAR File'). Es gibt drei Optionen für die Eclipse-Angebote (Juno) für die Bibliotheksverwaltung:

opt1: "Extract required libraries into generated JAR"
opt2: "Package required libraries into generated JAR"
opt3: "Copy required libraries into a sub-folder next to the generated JAR"

Normalerweise würde ich opt2 verwenden (und opt1 war definitiv fehlerhaft), aber nativer Code in einem der von mir verwendeten Gläser habe ich mit dem praktischen "jarinjar" -Trick entdeckt, den Eclipse nutzt, wenn Sie diese Option auswählen. Selbst nachdem mir klar wurde, dass ich opt3 benötige und dann diesen StackOverflow-Eintrag gefunden habe, habe ich noch einige Zeit gebraucht, um herauszufinden, wie ich mein Main außerhalb von Eclipse starten kann. Hier ist also, was für mich funktioniert hat, da es für andere nützlich ist ...


Wenn Sie Ihr Glas "fooBarTheJarFile.jar" genannt haben und alles so eingestellt ist, dass es in das Verzeichnis "/ theFully / qualifiedPath / toYourChosenDir" exportiert wird.

(Das Feld "Ziel exportieren" lautet: "/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar")

Nachdem Sie auf "Fertig stellen" geklickt haben, finden Sie Eclipse und legen alle Bibliotheken in einem Ordner mit dem Namen "fooBarTheJarFile_lib" in diesem Exportverzeichnis ab.

/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar
/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/SomeOtherJar01.jar
/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/SomeOtherJar02.jar
/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/SomeOtherJar03.jar
/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/SomeOtherJar04.jar

Sie können dann von überall auf Ihrem System starten mit:

java -classpath "/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/*" -jar  /theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar   package.path_to.the_class_with.your_main.TheClassWithYourMain

(Für Java-Neulinge: 'package.path_to.the_class_with.your_main' ist der deklarierte Paketpfad, den Sie oben in der Datei 'TheClassWithYourMain.java' finden, die die 'main (String [] args) {.. .} ', die Sie von außerhalb von Java ausführen möchten)


Die Falle, die Sie beachten sollten, ist, dass es nicht ausreicht, 'fooBarTheJarFile.jar' in der Liste der Jars auf Ihrem deklarierten Klassenpfad zu haben. Sie müssen explizit '-jar' deklarieren und den Speicherort dieses Jars neu deklarieren.

zB das bricht:

 java -classpath "/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar;/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/*"  somepackages.inside.yourJar.leadingToTheMain.TheClassWithYourMain

angepasst mit relativen Pfaden:

cd /theFully/qualifiedPath/toYourChosenDir/;
BREAKS:  java -cp "fooBarTheJarFile_lib/*"                                package.path_to.the_class_with.your_main.TheClassWithYourMain    
BREAKS:  java -cp ".;fooBarTheJarFile_lib/*"                              package.path_to.the_class_with.your_main.TheClassWithYourMain   
BREAKS:  java -cp ".;fooBarTheJarFile_lib/*"   -jar                       package.path_to.the_class_with.your_main.TheClassWithYourMain   
WORKS:   java -cp ".;fooBarTheJarFile_lib/*"   -jar  fooBarTheJarFile.jar package.path_to.the_class_with.your_main.TheClassWithYourMain   

(unter Verwendung der Java-Version "1.6.0_27"; über die OpenJDK 64-Bit-Server-VM unter Ubuntu 12.04)

Matt S.
quelle
3

Ich weiß nur, wie ich es individuell machen kann, zum Beispiel:

setenv CLASSPATH /User/username/newfolder/jarfile.jar:jarfile2.jar:jarfile3.jar:.

Ich hoffe, das hilft!

ParseTheData
quelle
Dies war vielleicht der einzige Weg im Jahr 2008, aber nicht mehr.
simo.3792
Das ist nicht das Schlimmste. Es ist ein Hack, aber ich habe dieses Set in meinem Bashrcfor jar in $(ls $HOME/bin/*.jar); do export CLASSPATH=$jar:$CLASSPATH; done
Devon Peticolas
3

Klasse von wepapp:

  > mvn clean install

  > java -cp "webapp/target/webapp-1.17.0-SNAPSHOT/WEB-INF/lib/tool-jar-1.17.0-SNAPSHOT.jar;webapp/target/webapp-1.17.0-SNAPSHOT/WEB-INF/lib/*" com.xx.xx.util.EncryptorUtils param1 param2
Mindaugas K.
quelle
2

Sie müssen sie alle separat hinzufügen. Wenn Sie wirklich nur ein Verzeichnis angeben müssen, können Sie alternativ alles in ein Verzeichnis aufheben und dieses Ihrem Klassenpfad hinzufügen. Ich empfehle diesen Ansatz jedoch nicht, da Sie bizarre Probleme bei der Versionierung und Unverwaltbarkeit von Klassenpfaden riskieren.

Daniel Spiewak
quelle
3
Dies war vielleicht der einzige Weg im Jahr 2008, aber nicht mehr.
simo.3792
2

Keine direkte Lösung, um / * auf -cp setzen zu können, aber ich hoffe, Sie können das folgende Skript verwenden, um die Situation für dynamische Klassenpfade und lib-Verzeichnisse ein wenig zu vereinfachen.

 libDir2Scan4jars="../test";cp=""; for j in `ls ${libDir2Scan4jars}/*.jar`; do if [ "$j" != "" ]; then cp=$cp:$j; fi; done; echo $cp| cut -c2-${#cp} > .tmpCP.tmp; export tmpCLASSPATH=`cat .tmpCP.tmp`; if [ "$tmpCLASSPATH" != "" ]; then echo .; echo "classpath set, you can now use  ~>         java -cp \$tmpCLASSPATH"; echo .; else echo .; echo "Error please check libDir2Scan4jars path"; echo .; fi; 

Skript für Linux, könnte auch für Windows ein ähnliches haben. Wenn das richtige Verzeichnis als Eingabe für die "libDir2Scan4jars" bereitgestellt wird; Das Skript scannt alle Jars, erstellt eine Klassenpfadzeichenfolge und exportiert sie in eine env-Variable "tmpCLASSPATH".

Sreesankar
quelle
2

macOS, aktueller Ordner

Für Java 13 unter macOS Mojave

Wenn sich alle Ihre .jarDateien im selben Ordner befinden, cdmachen Sie dies zu Ihrem aktuellen Arbeitsverzeichnis . Überprüfen Sie mitpwd .

Für die -classpathmüssen Sie zuerst die JAR-Datei für Ihre App auflisten. Fügen Sie mit einem Doppelpunkt :als Trennzeichen ein Sternchen hinzu *, um alle anderen JAR-Dateien im selben Ordner abzurufen. Zuletzt übergeben Sie den vollständigen Paketnamen der Klasse mit Ihrer mainMethode .

Beispiel: Für eine App in einer JAR-Datei my_app.jarmit einem Namen mainin einer Klasse Appin einem Paket mit dem Namen com.examplesowie einige benötigte Jars im selben Ordner:

java -classpath my_app.jar:* com.example.App
Basil Bourque
quelle
funktioniert nicht für Java 8
Greyshack
1

Stellen Sie sich eine JAR-Datei als Stamm einer Verzeichnisstruktur vor. Ja, Sie müssen alle separat hinzufügen.

Robert Van Hoose
quelle
1

Stellen Sie den Klassenpfad so ein, dass er für mehrere Jars und die Klassendateien des aktuellen Verzeichnisses geeignet ist.

CLASSPATH=${ORACLE_HOME}/jdbc/lib/ojdbc6.jar:${ORACLE_HOME}/jdbc/lib/ojdbc14.jar:${ORACLE_HOME}/jdbc/lib/nls_charset12.jar; 
CLASSPATH=$CLASSPATH:/export/home/gs806e/tops/jconn2.jar:.;
export CLASSPATH
Girdhar Singh Rathore
quelle
0

Ich habe mehrere Gläser in einem Ordner. Der folgende Befehl hat bei mir funktioniert JDK1.8, um alle im Ordner vorhandenen Gläser einzuschließen. Bitte beachten Sie, dass dies in Anführungszeichen gesetzt werden muss, wenn Sie ein Leerzeichen im Klassenpfad haben

Windows

Kompilieren: javac -classpath "C:\My Jars\sdk\lib\*" c:\programs\MyProgram.java

Laufen: java -classpath "C:\My Jars\sdk\lib\*;c:\programs" MyProgram

Linux

Kompilieren: javac -classpath "/home/guestuser/My Jars/sdk/lib/*" MyProgram.java

Laufen: java -classpath "/home/guestuser/My Jars/sdk/lib/*:/home/guestuser/programs" MyProgram

vkrams
quelle
-1

Ich versuche, Java-Datei entweder als JAR oder als Klassen in Ubuntu auszuführen. Ich habe bei beiden Optionen versagt. Die folgende Ausnahme ist die Ausgabe.

Download link: https://upload.cat/f694139f88c663b1

java org.statmetrics.Statmetric

oder

java -cp /home/elias/statmetrics/statmetrics.jar:. org.statmetrics.Statmetrics

oder

java -classpath "/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/*" -jar /home/elias/statmeics/statmetrics.jar org.statmetrics.Statmetrics

Exception in thread "Thread-0" java.lang.NoClassDefFoundError: javax/xml/bind/annotation/adapters/XmlAdapter
    at java.base/java.lang.ClassLoader.defineClass1(Native Method)
    at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016)
    at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174)
    at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:802)
    at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:700)
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:623)
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    at org.statmetrics.c.a(Unknown Source)
    at org.statmetrics.dw.a(Unknown Source)
    at org.statmetrics.dx.run(Unknown Source)
Caused by: java.lang.ClassNotFoundException: javax.xml.bind.annotation.adapters.XmlAdapter
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
    ... 12 more

Ich fand die Antwort:

Meine Dummheit.

Erster Schritt: Sie müssen das entsprechende Java einstellen: Ich hatte Java 11, aber ich habe die 8. Version als Java-Lib-Pfad festgelegt! - Sie können die Java-Version von hier aus einstellen:

  sudo update-alternatives --config java

2. Schritt: Führen Sie dann den folgenden Befehl aus, indem Sie den Pfad und die Dateinamen in den entsprechenden Pfad und die entsprechenden Dateien ändern:

  java -classpath "/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/*" -jar /home/elias/statmetrics/statmetrics.jar org.statmetrics.Statmetrics

Es wurde erfolgreich ausgeführt!

Elias EstatisticsEU
quelle