Mein Code wird in einer JAR-Datei ausgeführt, z. B. foo.jar , und ich muss im Code wissen, in welchem Ordner sich foo.jar befindet.
Wenn also foo.jar vorhanden ist C:\FOO\
, möchte ich diesen Pfad unabhängig von meinem aktuellen Arbeitsverzeichnis abrufen.
java
path
jar
executable-jar
Thiago Chaves
quelle
quelle
Antworten:
Ersetzen Sie "MyClass" durch den Namen Ihrer Klasse.
Offensichtlich wird dies seltsame Dinge bewirken, wenn Ihre Klasse von einem Nicht-Dateispeicherort geladen wurde.
quelle
toURI()
Schritt ist wichtig, um Probleme mit Sonderzeichen, einschließlich Leerzeichen und Pluszeichen, zu vermeiden. Der richtige Einzeiler ist: Diereturn new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().toURI());
VerwendungURLDecoder
funktioniert nicht für viele Sonderzeichen. Siehe meine Antwort unten für weitere Details.getProtectionDomain
ist null, wenn Sie Ihre Klasse von einem stracktrace erhalten:val strace = Thread.currentThread().getStackTrace; val path = strace(1).getClass.getProtectionDomain
Beste Lösung für mich:
Dies sollte das Problem mit Leerzeichen und Sonderzeichen lösen.
quelle
URLDecoder.decode(ClassLoader.getSystemClassLoader().getResource(".").getPath(), "UTF-8");
) unter Linux zu sein. Ich habe Windows jedoch nicht ausprobiert.URLDecoder
Sonderzeichen zu dekodieren. Insbesondere werden Zeichen wie+
fälschlicherweise in Leerzeichen dekodiert. Siehe meine Antwort für Details.Um das
File
für eine bestimmte zu erhaltenClass
, gibt es zwei Schritte:Class
in aURL
URL
in aFile
Es ist wichtig, beide Schritte zu verstehen und nicht zusammenzuführen.
Sobald Sie die haben
File
, können Sie anrufengetParentFile
, um den enthaltenen Ordner zu erhalten, wenn Sie dies benötigen.Schritt 1:
Class
bisURL
Wie in anderen Antworten erläutert, gibt es zwei Hauptmethoden, um eine
URL
für a relevante zu findenClass
.URL url = Bar.class.getProtectionDomain().getCodeSource().getLocation();
URL url = Bar.class.getResource(Bar.class.getSimpleName() + ".class");
Beide haben Vor- und Nachteile.
Der
getProtectionDomain
Ansatz liefert den Basisort der Klasse (z. B. die enthaltende JAR-Datei). Es ist jedoch möglich, dass die Sicherheitsrichtlinie der Java-LaufzeitSecurityException
beim AufrufengetProtectionDomain()
ausgelöst wird. Wenn Ihre Anwendung in einer Vielzahl von Umgebungen ausgeführt werden muss, ist es am besten, sie in allen Umgebungen zu testen.Der
getResource
Ansatz liefert den vollständigen URL-Ressourcenpfad der Klasse, von dem aus Sie zusätzliche Zeichenfolgenmanipulationen durchführen müssen. Es kann einfile:
Pfad sein, aber es kann auchjar:file:
oder sogar etwas Unangenehmeres sein,bundleresource://346.fwk2106232034:4/foo/Bar.class
wenn es innerhalb eines OSGi-Frameworks ausgeführt wird. UmgekehrtgetProtectionDomain
ergibt der Ansatz korrekt afile:
auch innerhalb von OSGi URL.Beachten Sie, dass beide
getResource("")
undgetResource(".")
in meinen Tests fehlgeschlagen sind, als sich die Klasse in einer JAR-Datei befand. Beide Aufrufe gaben null zurück. Daher empfehle ich stattdessen den oben gezeigten Aufruf Nr. 2, da er sicherer erscheint.Schritt 2:
URL
bisFile
In beiden Fällen ist
URL
der nächste Schritt , sobald Sie eine haben , die Konvertierung in aFile
. Dies ist seine eigene Herausforderung; siehe Kohsuke Kawaguchi Blog - Post über sie für weitere Informationen, aber kurz gesagt, können Sienew File(url.toURI())
, solange die URL vollständig wohlgeformt ist .Schließlich möchte ich sehr entmutigen verwenden
URLDecoder
. Einige Zeichen der URL:
und/
insbesondere sind keine gültigen URL-codierten Zeichen. Aus dem URLDecoder Javadoc:In der Praxis wird im
URLDecoder
Allgemeinen nichtIllegalArgumentException
wie oben bedroht geworfen . Wenn in Ihrem Dateipfad Leerzeichen codiert sind%20
, scheint dieser Ansatz zu funktionieren. Wenn Ihr Dateipfad jedoch andere nicht alphabetische Zeichen enthält, wie z. B.+
Probleme beimURLDecoder
Verwischen Ihres Dateipfads.Arbeitscode
Um diese Schritte auszuführen, haben Sie möglicherweise folgende Methoden:
Sie finden diese Methoden in der SciJava Common- Bibliothek:
quelle
Sie können auch verwenden:
quelle
Verwenden Sie ClassLoader.getResource (), um die URL für Ihre aktuelle Klasse zu finden.
Zum Beispiel:
(Dieses Beispiel stammt aus einer ähnlichen Frage .)
Um das Verzeichnis zu finden, müssen Sie die URL manuell zerlegen. Informationen zum Format einer JAR-URL finden Sie im JarClassLoader-Tutorial .
quelle
NPE
weil Sie die gestellte Frage nicht beantwortet haben (Pfad zu JAR dir wurde gestellt und Sie haben auf eine völlig andere Frage geantwortet: Pfad zur Klasse). 2. Wie von anderen erwähnt, und ich habe das gleiche Problem, funktioniert es nicht für Applets. 3. Der zurückgegebene Pfad ist überhaupt nicht kanonisch dargestellt :jar:file:/listener/build/libs/listener-1.0.0-all.jar!/shared/Test.class
.Ich bin überrascht zu sehen, dass keiner kürzlich vorgeschlagen hat, es zu verwenden
Path
. Hier folgt ein Zitat: " DiePath
Klasse enthält verschiedene Methoden, mit denen Informationen über den Pfad abgerufen, auf Elemente des Pfads zugegriffen, der Pfad in andere Formen konvertiert oder Teile eines Pfads extrahiert werden können. "Eine gute Alternative ist es daher, das
Path
Objekt wie folgt zu erhalten :quelle
Die einzige Lösung, die für mich unter Linux, Mac und Windows funktioniert:
quelle
Ich hatte das gleiche Problem und habe es so gelöst:
Ich hoffe ich habe dir geholfen.
quelle
Hier ist ein Upgrade auf andere Kommentare, die mir für die Einzelheiten von unvollständig erscheinen
quelle
URLDecoder
Sonderzeichen zu dekodieren. Insbesondere werden Zeichen wie+
fälschlicherweise in Leerzeichen dekodiert. Siehe meine Antwort für Details.URLDecoder
dient trotz seines Namens zum Dekodieren von URL- und Formularparameternamen und -werten, nicht von URLs.Um den Pfad zum Ausführen der JAR-Datei zu ermitteln, habe ich die oben genannten Lösungen untersucht und alle Methoden ausprobiert, bei denen Unterschiede bestehen. Wenn dieser Code in der Eclipse-IDE ausgeführt wird, sollten alle in der Lage sein, den Pfad der Datei einschließlich der angegebenen Klasse zu finden und eine angegebene Datei mit dem gefundenen Pfad zu öffnen oder zu erstellen.
Es ist jedoch schwierig, wenn die ausführbare JAR-Datei direkt oder über die Befehlszeile ausgeführt wird. Dies schlägt fehl, da der Pfad der JAR-Datei, der mit den oben genannten Methoden abgerufen wurde, einen internen Pfad in der JAR-Datei angibt, dh immer einen Pfad angibt wie
rsrc: Projektname (vielleicht sollte ich sagen, dass es der Paketname der Hauptklassendatei ist - die angegebene Klasse)
Ich kann den Pfad rsrc: ... nicht in einen externen Pfad konvertieren. Wenn die JAR-Datei außerhalb der Eclipse-IDE ausgeführt wird, kann der Pfad der JAR-Datei nicht abgerufen werden.
Die einzige Möglichkeit, den Pfad zum Ausführen der JAR-Datei außerhalb der Eclipse-IDE abzurufen, ist
Diese Codezeile gibt möglicherweise den lebenden Pfad (einschließlich des Dateinamens) der laufenden JAR-Datei zurück (beachten Sie, dass der Rückgabepfad nicht das Arbeitsverzeichnis ist), da das Java-Dokument und einige Leute sagten, dass die Pfade aller Klassendateien zurückgegeben werden im selben Verzeichnis, aber da meine Tests, wenn sie im selben Verzeichnis viele JAR-Dateien enthalten, nur den Pfad zum Ausführen von JAR zurückgeben (über das Problem mit mehreren Pfaden, das tatsächlich in der Eclipse aufgetreten ist).
quelle
java.class.path
kann mehrwertig sein. Einer dieser Werte liefert sicherlich das Verzeichnis oder die JAR-Datei, in der sich die aktuelle Klasse befindet, aber welcher?Andere Antworten scheinen auf die Codequelle zu verweisen, bei der es sich um den Speicherort der Jar-Datei handelt, bei dem es sich nicht um ein Verzeichnis handelt.
Verwenden
quelle
Die oben ausgewählte Antwort funktioniert nicht, wenn Sie Ihr JAR ausführen, indem Sie in der Gnome-Desktop-Umgebung darauf klicken (nicht in einem Skript oder Terminal).
Stattdessen finde ich es gut, dass die folgende Lösung überall funktioniert:
quelle
URLDecoder
Sonderzeichen zu dekodieren. Insbesondere werden Zeichen wie+
fälschlicherweise in Leerzeichen dekodiert. Siehe meine Antwort für Details.NullPointerException
NPE
wenn es keine Ressourcen in JAR gibt.Eigentlich ist hier eine bessere Version - die alte ist fehlgeschlagen, wenn ein Ordnername ein Leerzeichen enthält.
Wenn Sie mit Applets fehlschlagen, haben Sie normalerweise sowieso keinen Zugriff auf lokale Dateien. Ich weiß nicht viel über JWS, aber um lokale Dateien zu verarbeiten, ist es möglicherweise nicht möglich, die App herunterzuladen.
quelle
Ich habe versucht, den Glaslaufpfad mit zu bekommen
c: \ app> java -jar application.jar
Beim Ausführen der JAR-Anwendung "application.jar" unter Windows im Ordner " c: \ app " lautete der Wert der String-Variablen "folder" " \ c: \ app \ application.jar ", und ich hatte Probleme beim Testen die Richtigkeit des Pfades
Also habe ich versucht, "Test" zu definieren als:
Pfad in einem richtigen Format wie " c: \ app " anstelle von " \ c: \ app \ application.jar " zu erhalten, und ich bemerkte, dass es funktioniert.
quelle
Die einfachste Lösung besteht darin, den Pfad als Argument beim Ausführen des JARs zu übergeben.
Sie können dies mit einem Shell-Skript automatisieren (.bat in Windows, .sh an einer anderen Stelle):
Ich habe
.
das aktuelle Arbeitsverzeichnis übergeben.AKTUALISIEREN
Möglicherweise möchten Sie die JAR-Datei in einem Unterverzeichnis speichern, damit Benutzer nicht versehentlich darauf klicken. Ihr Code sollte auch überprüfen, ob die Befehlszeilenargumente angegeben wurden, und eine gute Fehlermeldung anzeigen, wenn die Argumente fehlen.
quelle
Ich musste viel herumspielen, bevor ich endlich eine funktionierende (und kurze) Lösung fand.
Es ist möglich, dass das
jarLocation
mit einem Präfix wiefile:\
oder geliefert wirdjar:file\
, das mit verwendet werden kannString#substring()
.quelle
Der Pfad bezieht sich immer auf die Ressource in der JAR-Datei.
quelle
String path = new File(getClass().getResource("").getPath()).getParentFile().getParent(); File jarDir = new File(path.substring(5));
getResource("")
undgetResource(".")
fehlgeschlagen in meinen Tests, als sich die Klasse in einer JAR-Datei befand; Beide Aufrufe gaben null zurück.NullPointerException
.Funktioniert gut unter Windows
quelle
Etwas , das frustrierend ist, dass , wenn Sie in Eclipse entwickeln ,
MyClass.class.getProtectionDomain().getCodeSource().getLocation()
das zurückgibt/bin
Verzeichnis , das ist sehr gut, aber wenn man es in ein Gefäß zu kompilieren, enthält der Pfad der/myjarname.jar
Teil, der Ihnen illegale Dateinamen gibt.Damit der Code sowohl in der ide als auch nach dem Kompilieren in ein Glas funktioniert, verwende ich den folgenden Code:
quelle
Ich bin mir bei den anderen nicht wirklich sicher, aber in meinem Fall funktionierte es nicht mit einem "Runnable JAR" und ich habe es zum Laufen gebracht, indem ich Codes aus der Antwort von phchen2 und einem anderen über diesen Link zusammengesetzt habe: Wie erhalte ich den Pfad einer laufenden JAR-Datei? Der Code:
quelle
Ich habe dort oben mehrere Lösungen ausprobiert, aber keine lieferte korrekte Ergebnisse für den (wahrscheinlich speziellen) Fall, dass das ausführbare JAR mit "Externe Bibliotheken verpacken" in Eclipse exportiert wurde. Aus irgendeinem Grund führen alle auf der ProtectionDomain basierenden Lösungen in diesem Fall zu null.
Durch die Kombination einiger der oben genannten Lösungen gelang es mir, den folgenden Arbeitscode zu erreichen:
quelle
Versuche dies:
quelle
Diese Methode, die aus dem Code im Archiv aufgerufen wird, gibt den Ordner zurück, in dem sich die JAR-Datei befindet. Es sollte entweder unter Windows oder unter Unix funktionieren.
Abgeleitet vom Code unter: Bestimmen Sie, ob JAR ausgeführt wird
quelle
Erwähnen Sie, dass es nur eingecheckt ist,
Windows
aber ich denke, es funktioniert perfekt auf anderen Betriebssystemen [Linux,MacOs,Solaris
] :).Ich hatte 2
.jar
Dateien im selben Verzeichnis. Ich wollte von der einen.jar
Datei die andere.jar
Datei starten, die sich im selben Verzeichnis befindet.Das Problem ist, dass beim Starten aus
cmd
dem aktuellen Verzeichnis istsystem32
.;][[;'57f2g34g87-8+9-09!2#@!$%^^&()
oder durchgeführt habe, ziemlich gut zu funktionieren()%&$%^@#
es funktioniert gut.ProcessBuilder
mit dem folgenden wie folgt:🍂 ..
🍂
getBasePathForClass(Class<?> classs)
:quelle
Dieser Code hat bei mir funktioniert:
quelle
Mit diesem Code konnte ich feststellen, ob das Programm in einer JAR-Datei oder IDE ausgeführt wird:
Wenn ich den vollständigen Windows-Pfad der JAR-Datei abrufen muss, verwende ich diese Methode:
Mein vollständiger Code, der mit einer Spring Boot-Anwendung unter Verwendung der
CommandLineRunner
Implementierung arbeitet, um sicherzustellen, dass die Anwendung immer in einer Konsolenansicht ausgeführt wird (versehentlich doppelte Klicks im JAR-Dateinamen), verwende ich den nächsten Code:quelle
Ich schreibe in Java 7 und teste in Windows 7 mit der Laufzeit von Oracle und Ubuntu mit der Open Source-Laufzeit. Dies funktioniert perfekt für diese Systeme:
Der Pfad für das übergeordnete Verzeichnis einer laufenden JAR-Datei (vorausgesetzt, die Klasse, die diesen Code aufruft, ist ein direktes untergeordnetes Element des JAR-Archivs selbst):
Der Pfad von foo.jar wäre also:
Auch dies wurde auf keinem Mac oder älteren Windows getestet
quelle
Der
getProtectionDomain
Ansatz funktioniert manchmal nicht, z. B. wenn Sie das JAR für einige der Java-Kernklassen finden müssen (z. B. in meiner FallklasseStringBuilder
innerhalb von IBM JDK). Das Folgende funktioniert jedoch nahtlos:quelle
Ich habe eine andere Möglichkeit, den String-Speicherort einer Klasse zu ermitteln.
Die Ausgabezeichenfolge hat die Form
Die Leerzeichen und andere Zeichen werden behandelt und in der Form ohne
file:/
. So wird es einfacher zu bedienen sein.quelle