Mon code s'exécute dans un fichier JAR, par exemple foo.jar , et j'ai besoin de savoir, dans le code, dans quel dossier se trouve foo.jar .
Donc, si foo.jar est dedansC:\FOO\
, je veux obtenir ce chemin quel que soit mon répertoire de travail actuel.
java
path
jar
executable-jar
Thiago Chaves
la source
la source
Réponses:
Remplacez "MyClass" par le nom de votre classe.
Évidemment, cela fera des choses étranges si votre classe a été chargée à partir d'un emplacement non-fichier.
la source
toURI()
étape est essentielle pour éviter les problèmes avec les caractères spéciaux, y compris les espaces et les avantages. La ligne droite correcte est: L'return new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().toURI());
utilisationURLDecoder
ne fonctionne pas pour de nombreux caractères spéciaux. Voir ma réponse ci-dessous pour plus de détails.getProtectionDomain
est nul si vous obtenez votre classe à partir d'une piste de suivi:val strace = Thread.currentThread().getStackTrace; val path = strace(1).getClass.getProtectionDomain
La meilleure solution pour moi:
Cela devrait résoudre le problème avec les espaces et les caractères spéciaux.
la source
URLDecoder.decode(ClassLoader.getSystemClassLoader().getResource(".").getPath(), "UTF-8");
) sous Linux. Cependant, je n'ai pas essayé sous Windows.URLDecoder
pour décoder les caractères spéciaux. En particulier, des personnages comme+
seront décodés par erreur dans les espaces. Voir ma réponse pour plus de détails.Pour obtenir le
File
pour une donnéeClass
, il y a deux étapes:Class
enURL
URL
enFile
Il est important de comprendre les deux étapes et de ne pas les confondre.
Une fois que vous avez le
File
, vous pouvez appelergetParentFile
pour obtenir le dossier contenant, si c'est ce dont vous avez besoin.Étape 1:
Class
pourURL
Comme indiqué dans d'autres réponses, il existe deux façons principales de trouver un
URL
élément pertinent pour aClass
.URL url = Bar.class.getProtectionDomain().getCodeSource().getLocation();
URL url = Bar.class.getResource(Bar.class.getSimpleName() + ".class");
Les deux ont des avantages et des inconvénients.
L'
getProtectionDomain
approche donne l'emplacement de base de la classe (par exemple, le fichier JAR contenant). Cependant, il est possible que la politique de sécurité du runtime Java seSecurityException
déclenche lors de l'appelgetProtectionDomain()
, donc si votre application doit s'exécuter dans une variété d'environnements, il est préférable de tester dans chacun d'eux.L'
getResource
approche produit le chemin d'accès complet aux ressources URL de la classe, à partir de laquelle vous devrez effectuer une manipulation de chaîne supplémentaire. Il peut s'agir d'unfile:
chemin, mais il peut également l'êtrejar:file:
ou même quelque chose de plus méchant commebundleresource://346.fwk2106232034:4/foo/Bar.class
lors de l'exécution dans un cadre OSGi. Inversement, l'getProtectionDomain
approche produit correctement unefile:
URL même depuis OSGi.Notez que les deux
getResource("")
et ontgetResource(".")
échoué dans mes tests, lorsque la classe résidait dans un fichier JAR; les deux invocations ont retourné null. Je recommande donc plutôt l'invocation n ° 2 ci-dessus, car elle semble plus sûre.Étape 2:
URL
pourFile
Quoi qu'il en soit, une fois que vous avez un
URL
, l'étape suivante est convertie en aFile
. C'est son propre défi; voir le blog de Kohsuke Kawaguchi à ce sujet pour plus de détails, mais en bref, vous pouvez l'utilisernew File(url.toURI())
tant que l'URL est complètement bien formée.Enfin, je découragerais fortement l' utilisation
URLDecoder
. Certains caractères de l'URL,:
et/
en particulier, ne sont pas des caractères codés URL valides. Depuis l' URLDecoder Javadoc:En pratique,
URLDecoder
ne jette généralement pasIllegalArgumentException
comme menacé ci-dessus. Et si votre chemin d'accès au fichier comporte des espaces codés en tant que%20
, cette approche peut sembler fonctionner. Cependant, si votre chemin d'accès au fichier contient d'autres caractères non alphamériques tels que+
vous aurez des problèmes avec laURLDecoder
modification de votre chemin d'accès au fichier.Code de travail
Pour réaliser ces étapes, vous pouvez avoir des méthodes comme les suivantes:
Vous pouvez trouver ces méthodes dans la bibliothèque commune de SciJava :
la source
Vous pouvez aussi utiliser:
la source
Utilisez ClassLoader.getResource () pour trouver l'URL de votre classe actuelle.
Par exemple:
(Cet exemple tiré d' une question similaire .)
Pour trouver le répertoire, vous devez ensuite démonter l'URL manuellement. Voir le didacticiel JarClassLoader pour le format d'une URL jar.
la source
NPE
parce que vous n'avez pas répondu à la question qui a été posée (le chemin vers le répertoire JAR a été demandé et vous avez répondu sur une question absolument différente: chemin vers la classe). 2. Comme indiqué par d'autres, et j'ai eu le même problème, cela ne fonctionne pas pour les applets. 3. chemin retour ne soit pas la représentation canonique de chemin du tout:jar:file:/listener/build/libs/listener-1.0.0-all.jar!/shared/Test.class
.Je suis surpris de voir qu'aucun n'a récemment proposé d'utiliser
Path
. Voici une citation: " LaPath
classe comprend diverses méthodes qui peuvent être utilisées pour obtenir des informations sur le chemin d'accès, accéder aux éléments du chemin d'accès, convertir le chemin d'accès vers d'autres formes ou extraire des parties d'un chemin d'accès "Ainsi, une bonne alternative consiste à obtenir l'
Path
objest comme:la source
La seule solution qui fonctionne pour moi sur Linux, Mac et Windows:
la source
J'ai eu le même problème et je l'ai résolu de cette façon:
J'espère que je t'ai aidé.
la source
Voici la mise à niveau vers d'autres commentaires, qui me semblent incomplets pour les spécificités de
la source
URLDecoder
pour décoder les caractères spéciaux. En particulier, des personnages comme+
seront décodés par erreur dans les espaces. Voir ma réponse pour plus de détails.URLDecoder
, malgré son nom, sert au décodage des URL et des noms et valeurs des paramètres de formulaire, et non des URL.Pour obtenir le chemin de l'exécution du fichier jar, j'ai étudié les solutions ci-dessus et essayé toutes les méthodes qui existent quelque part. Si ces codes s'exécutent dans Eclipse IDE, ils devraient tous pouvoir trouver le chemin du fichier, y compris la classe indiquée, et ouvrir ou créer un fichier indiqué avec le chemin trouvé.
Mais il est difficile, lorsque vous exécutez le fichier jar exécutable directement ou via la ligne de commande, il échouera car le chemin du fichier jar obtenu à partir des méthodes ci-dessus donnera un chemin interne dans le fichier jar, c'est-à-dire qu'il donne toujours un chemin comme
rsrc: project-name (peut-être devrais-je dire que c'est le nom du package du fichier de classe principale - la classe indiquée)
Je ne peux pas convertir le chemin rsrc: ... en chemin externe, c'est-à-dire que lorsque vous exécutez le fichier jar en dehors de l'IDE Eclipse, il ne peut pas obtenir le chemin du fichier jar.
Le seul moyen possible d'obtenir le chemin d'exécution du fichier jar en dehors de l'IDE Eclipse est
cette ligne de code peut renvoyer le chemin vivant (y compris le nom de fichier) du fichier jar en cours d'exécution (notez que le chemin de retour n'est pas le répertoire de travail), car le document java et certaines personnes ont dit qu'il retournerait les chemins de tous les fichiers de classe dans le même répertoire, mais comme mes tests si dans le même répertoire incluent de nombreux fichiers jar, il ne renvoie que le chemin de l'exécution du jar (à propos du problème des chemins multiples, il est en effet arrivé dans Eclipse).
la source
java.class.path
peut être à plusieurs valeurs. L'une de ces valeurs fournira certainement le répertoire ou le fichier JAR où se trouve la classe actuelle, mais lequel?D'autres réponses semblent pointer vers la source de code qui est l'emplacement du fichier Jar qui n'est pas un répertoire.
Utilisation
la source
la réponse sélectionnée ci-dessus ne fonctionne pas si vous exécutez votre bocal en cliquant dessus depuis l'environnement de bureau Gnome (pas depuis un script ou un terminal).
Au lieu de cela, j'ai aimé que la solution suivante fonctionne partout:
la source
URLDecoder
pour décoder les caractères spéciaux. En particulier, des personnages comme+
seront décodés par erreur dans les espaces. Voir ma réponse pour plus de détails.NullPointerException
NPE
s'il n'y a pas de ressources dans JAR.En fait, voici une meilleure version - l'ancienne a échoué si un nom de dossier avait un espace.
Quant à l'échec des applets, vous n'auriez généralement pas accès aux fichiers locaux de toute façon. Je ne connais pas grand-chose à JWS, mais pour gérer les fichiers locaux, il pourrait ne pas être possible de télécharger l'application.?
la source
J'ai essayé d'obtenir le chemin du pot en utilisant
c: \ app> java -jar application.jar
En exécutant l'application jar nommée "application.jar", sous Windows dans le dossier " c: \ app ", la valeur de la variable String "folder" était " \ c: \ app \ application.jar " et j'ai eu des problèmes de test pour correction du chemin
J'ai donc essayé de définir "test" comme:
pour obtenir le chemin dans un format correct comme " c: \ app " au lieu de " \ c: \ app \ application.jar " et j'ai remarqué que cela fonctionne.
la source
La solution la plus simple consiste à passer le chemin en argument lors de l'exécution du bocal.
Vous pouvez automatiser cela avec un script shell (.bat sous Windows, .sh n'importe où ailleurs):
J'ai utilisé
.
pour passer le répertoire de travail actuel.MISE À JOUR
Vous voudrez peut-être coller le fichier jar dans un sous-répertoire afin que les utilisateurs ne cliquent pas accidentellement dessus. Votre code doit également vérifier que les arguments de ligne de commande ont été fournis et fournir un bon message d'erreur si les arguments sont manquants.
la source
J'ai dû beaucoup m'amuser avant de trouver enfin une solution (et courte) de travail.
Il est possible que le
jarLocation
soit accompagné d'un préfixe commefile:\
oujar:file\
, qui peut être supprimé à l'aide deString#substring()
.la source
Le chemin fait toujours référence à la ressource dans le fichier jar.
la source
String path = new File(getClass().getResource("").getPath()).getParentFile().getParent(); File jarDir = new File(path.substring(5));
getResource("")
et ontgetResource(".")
échoué dans mes tests, lorsque la classe résidait dans un fichier JAR; les deux invocations ont retourné null.NullPointerException
.Fonctionne bien sous Windows
la source
Ce qui est frustrant, c'est que lorsque vous développez dans Eclipse
MyClass.class.getProtectionDomain().getCodeSource().getLocation()
renvoie le/bin
répertoire qui est génial, mais lorsque vous le compilez dans un bocal, le chemin inclut la/myjarname.jar
partie qui vous donne des noms de fichiers illégaux.Pour que le code fonctionne à la fois dans l'idé et une fois qu'il est compilé dans un bocal, j'utilise le morceau de code suivant:
la source
Pas vraiment sûr des autres, mais dans mon cas, cela ne fonctionnait pas avec un "pot exécutable" et je l'ai fait fonctionner en fixant les codes ensemble à partir de la réponse phchen2 et un autre à partir de ce lien: Comment obtenir le chemin d'un fichier JAR en cours d'exécution? Le code:
la source
J'ai essayé plusieurs des solutions là-haut, mais aucune n'a donné de résultats corrects dans le cas (probablement spécial) où le pot exécutable a été exporté avec "Empaqueter des bibliothèques externes" dans Eclipse. Pour une raison quelconque, toutes les solutions basées sur le ProtectionDomain aboutissent à null dans ce cas.
En combinant certaines solutions ci-dessus, j'ai réussi à obtenir le code de travail suivant:
la source
Essaye ça:
la source
Cette méthode, appelée à partir du code dans l'archive, renvoie le dossier où se trouve le fichier .jar. Cela devrait fonctionner sous Windows ou Unix.
Dérivé du code à: déterminer si l'exécution à partir de JAR
la source
Mentionnez qu'il est enregistré uniquement
Windows
mais je pense que cela fonctionne parfaitement sur d'autres systèmes d'exploitation [Linux,MacOs,Solaris
] :).J'avais 2
.jar
fichiers dans le même répertoire. Je voulais à partir d'un.jar
fichier pour démarrer l'autre.jar
fichier qui se trouve dans le même répertoire.Le problème est que lorsque vous le démarrez à partir du
cmd
répertoire en cours, c'estsystem32
.;][[;'57f2g34g87-8+9-09!2#@!$%^^&()
ou()%&$%^@#
cela fonctionne bien.ProcessBuilder
avec le ci-dessous comme suit:🍂 ..
🍂
getBasePathForClass(Class<?> classs)
:la source
Ce code a fonctionné pour moi:
la source
Ce code a fonctionné pour moi pour identifier si le programme est exécuté dans un fichier JAR ou IDE:
Si j'ai besoin d'obtenir le chemin complet Windows du fichier JAR, j'utilise cette méthode:
Mon code complet fonctionnant avec une application Spring Boot utilisant l'
CommandLineRunner
implémentation, pour garantir que l'application soit toujours exécutée dans une vue console (Double-clique par erreur dans le nom du fichier JAR), j'utilise le code suivant:la source
J'écris en Java 7 et teste sous Windows 7 avec le runtime d'Oracle et Ubuntu avec le runtime open source. Cela fonctionne parfaitement pour ces systèmes:
Le chemin d'accès au répertoire parent de tout fichier jar en cours d'exécution (en supposant que la classe appelant ce code est un enfant direct de l'archive jar elle-même):
Ainsi, le chemin de foo.jar serait:
Encore une fois, cela n'a été testé sur aucun Mac ou Windows plus ancien
la source
L'
getProtectionDomain
approche peut ne pas fonctionner parfois, par exemple lorsque vous devez trouver le fichier jar pour certaines des classes Java principales (par exemple, dans maStringBuilder
classe de cas dans IBM JDK), cependant, la procédure suivante fonctionne de manière transparente:la source
J'ai une autre façon d'obtenir l'emplacement String d'une classe.
La chaîne de sortie aura la forme de
Les espaces et autres caractères sont traités, et sous la forme sans
file:/
. Ce sera donc plus facile à utiliser.la source