Comment obtenir le chemin d'accès d'un fichier JAR?
Mon code s'exécute à l'intérieur d'un fichier JAR, dire foo.jar et j'ai besoin de savoir, dans le code, dans le dossier de la course foo.jar est.
Donc, si foo.jar est dans C:\FOO\
, je veux obtenir ce chemin peu importe ce que mon répertoire de travail actuel est.
Voir la réponse de Fab pour une solution qui fonctionne lorsque les chemins d'accès comprennent des espaces. Notez également que certaines réponses ci-dessous l'adresse de la question dans le titre (jar chemin), certains traitent de la question elle-même (chemin du dossier contenant jar), et certains offrent des chemins de classes à l'intérieur du fichier jar.
Méfiez-vous lors de l'utilisation de ANT! ============== J'appelle String path = SomeClass.classe.getProtectionDomain().getCodeSource().getLocation().getPath(); et d'obtenir: /C:/apache-ant-1.7.1/lib/ant.jar Pas très utile!
Intéressant. Le code d'origine dans lequel j'ai utilisé cela n'a jamais été exécuté en ant, il n'est donc pas un problème pour moi.
Fancellu, j'ai vécu exactement ce que vous avez décrit. Travaux au cours de dev, échoue lors de la construction du pot.
Méfiez-vous lors de l'utilisation de ANT! ============== J'appelle String path = SomeClass.classe.getProtectionDomain().getCodeSource().getLocation().getPath(); et d'obtenir: /C:/apache-ant-1.7.1/lib/ant.jar Pas très utile!
Intéressant. Le code d'origine dans lequel j'ai utilisé cela n'a jamais été exécuté en ant, il n'est donc pas un problème pour moi.
Fancellu, j'ai vécu exactement ce que vous avez décrit. Travaux au cours de dev, échoue lors de la construction du pot.
OriginalL'auteur Thiago Chaves | 2008-11-26
Vous devez vous connecter pour publier un commentaire.
Remplacer "MyClass" avec le nom de votre classe
Évidemment, cela va faire des choses bizarres si votre classe a été chargé à partir d'un non-emplacement du fichier.
toURI()
étape est essentielle pour éviter des problèmes avec les caractères spéciaux, y compris les espaces et les points positifs. Le bon one-liner est:return new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().toURI());
à l'Aide deURLDecoder
ne fonctionne pas pour de nombreux caractères spéciaux. Voir ma réponse ci-dessous pour plus de détails.Remarque: ceci renvoie le chemin d'accès, y compris le nom de fichier jar
N'est-ce pas pointer vers le fichier jar, au lieu de le répertoire d'exécution? Vous aurez à faire sur le résultat getParentFile() pour ce travail.
Aussi,
getProtectionDomain
est nulle, si vous êtes l'obtention de votre classe à partir d'un stracktrace:val strace = Thread.currentThread().getStackTrace; val path = strace(1).getClass.getProtectionDomain
À l'aide de cette méthode avec Java 8; le placement de cette méthode dans une classe qui est dans un Jar externe, chargé par classe de chemin, le chemin d'accès de l'extérieur le pot va être donné au lieu de le Bocal.
OriginalL'auteur Zarkonnen
Meilleure solution pour moi:
Ce qui devrait résoudre le problème avec les espaces et caractères spéciaux.
/ n'est pas nécessairement le séparateur de chemin. Vous devriez faire (new File(path)).getParentFile().getPath() à la place.
Pas de problèmes avec le fichier JAR du nom de l'être ajoutés ici. La conversion UTF semble être la solution parfaite en combinaison avec @Iviggiani (
URLDecoder.decode(ClassLoader.getSystemClassLoader().getResource(".").getPath(), "UTF-8");
) sur Linux. Cependant, je n'ai pas essayé sur Windows.Merci, cela m'a permis de charger des fichiers externes à mon POT avec FileInputStream à la fois Linux et Windows. Juste eu à ajouter de la decodedpath en face du nom du fichier...
Attention: il est recommandé de ne pas utiliser
URLDecoder
de décoder les caractères spéciaux. En particulier, des personnages comme+
sera tort décodé espaces. Voir ma réponse pour plus de détails.OriginalL'auteur Fab
Pour obtenir le
File
pour unClass
, il y a deux étapes:Class
à unURL
URL
à unFile
Il est important de comprendre à la fois des mesures, et non pas l'amalgame entre eux.
Une fois que vous avez la
File
, vous pouvez appelergetParentFile
pour obtenir le dossier contenant, si c'est ce que vous avez besoin.Étape 1:
Class
àURL
Tel que discuté dans d'autres réponses, il y a deux grandes façons de trouver un
URL
pertinents pour uneClass
.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.
La
getProtectionDomain
approche donne l'emplacement de la base de la classe (par exemple, le fichier JAR contenant). Toutefois, il est possible que le runtime Java de la politique de sécurité va lancerSecurityException
lors de l'appel degetProtectionDomain()
, donc, si votre application a besoin pour fonctionner dans une variété d'environnements, il est préférable de le tester dans tous les d'entre eux.La
getResource
approche donne l'URL complète chemin d'accès aux ressources de la classe, à partir de laquelle vous devrez effectuer supplémentaires de manipulation de chaîne. Il peut être unfile:
chemin, mais il pourrait aussi êtrejar:file:
ou même quelque chose de plus méchant commebundleresource://346.fwk2106232034:4/foo/Bar.class
lors de l'exécution à l'intérieur d'un framework OSGi. À l'inverse, lagetProtectionDomain
approche correctement donne unfile:
URL, même de l'intérieur OSGi.Noter que les deux
getResource("")
etgetResource(".")
échoué dans mes tests, lorsque la classe se trouvaient à l'intérieur d'un fichier JAR; les deux invocations retourné null. Je recommande donc le n ° 2 de l'invocation indiqué ci-dessus au lieu de cela, comme il semble plus sûr.Étape 2:
URL
àFile
De toute façon, une fois que vous avez un
URL
, la prochaine étape est de les convertir à unFile
. C'est son propre défi; voir Kohsuke nous Kawaguchi blog post à ce sujet pour plus de détails, mais en bref, vous pouvez utilisernew File(url.toURI())
tant que l'URL est complètement bien formé.Enfin, j' décourage fortement à l'aide de
URLDecoder
. Certains caractères de l'URL,:
et/
en particulier, ne sont pas valides URL caractères encodés. À partir de la URLDecoder Javadoc:Dans la pratique,
URLDecoder
généralement ne pas jeterIllegalArgumentException
menacées ci-dessus. Et si votre chemin d'accès de fichier avec des espaces codés comme des%20
, cette approche peut sembler fonctionner. Toutefois, si votre chemin d'accès du fichier à d'autres fins non alphameric des caractères tels que+
vous avez des problèmes avecURLDecoder
modificateur de votre chemin d'accès au fichier.Code de travail
À la réalisation de ces étapes, vous pourriez avoir des méthodes comme suit:
Vous pouvez trouver ces méthodes dans le SciJava Commune bibliothèque:
Concernant la sécurité, je crois que j'ai trouvé que Java WebStart ne le permettent pas.
OriginalL'auteur ctrueden
Vous pouvez également utiliser:
OriginalL'auteur Benny Neugebauer
Utilisation Du Chargeur De Classe.getResource() pour trouver l'URL de votre classe actuelle.
Par exemple:
(Cet exemple pris de une question similaire.)
Pour trouver le répertoire, vous pouvez avoir besoin de prendre part à l'URL manuellement. Voir la JarClassLoader tutoriel pour le format d'un pot de l'URL.
Si c'est obscurci, utilisez le Test.classe.getName() et ne appropriées munging.
il y a tellement de problèmes avec votre réponse: 1. Il n'y aura pas
NPE
parce que vous n'avez pas répondu sur la question qui a été posée (chemin du POT de dir a demandé et vous avez répondu sur absolument autre question: chemin d'accès à la classe). 2. Comme indiqué par d'autres, et j'ai eu le même problème, il ne fonctionne pas pour les applets. 3. Retourné chemin n'est pas canonique chemin de représentation à tous:jar:file:/listener/build/libs/listener-1.0.0-all.jar!/shared/Test.class
.1) La dernière ligne de mon post indique que vous devez regarder l'URL et le prendre à part pour obtenir le fichier jar. Je suis d'accord ce n'est pas la réponse la plus complète, mais je ne pense pas que c'est vraiment trop mauvais pour être la peine d'argumenter au sujet (en particulier 10 ans plus tard...) 2) les Applets n'ont pas été mentionnés dans les commentaires ici - assez étrangement, je n'ai pas le temps de regarder tous les commentaires sur toutes les réponses sur les questions que j'ai à poster une réponse. 3) Encore une fois, j'ai le lien pour le format du pot de l'URL.
Est-il la meilleure réponse que j'ai jamais écrit? Nope. Est-il aussi mauvais que tu fais ça? Non, je ne le pense pas. (Notamment en termes de revendications que vous faites autour de lui jeter un NPE, dont il n'a pas.) Je vous suggère d'ajouter votre propre réponse au lieu de faire une histoire à ce sujet. Que serait une approche plus positive.
OriginalL'auteur Jon Skeet
Je suis surpris de voir qu'aucun 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 à des éléments de la voie, convertissez le chemin d'accès à d'autres formes ou d'en extraire des parties d'un chemin"Ainsi, une bonne alternative est d'obtenir le
Path
objeu:Oui, bien sûr...
Je confirme, cela fonctionne avec les chemins avec espaces
OriginalL'auteur mat_boy
La seule solution qui fonctionne pour moi sur Linux, Mac et Windows:
OriginalL'auteur Dmitry Trofimov
J'ai eu le même problème et je l'ai résolu de cette façon:
J'espère avoir été utile pour vous.
OriginalL'auteur Charlie
Ici de la mise à niveau à d'autres commentaires, qui me semblent incomplètes pour les spécificités de
URLDecoder
de décoder les caractères spéciaux. En particulier, des personnages comme+
sera tort décodé espaces. Voir ma réponse pour plus de détails.À l'aide de caractères spéciaux dans les noms de fichiers n'est pas recommandé.
URLDecoder
, en dépit de son nom, est pour le décodage de l'URL et de la forme des noms de paramètres et de valeurs, pas les Url.OriginalL'auteur Zon
Pour obtenir le chemin d'accès de l'exécution de fichier jar, j'ai étudié les solutions ci-dessus et essayé toutes les méthodes qui existent certaine différence les uns des autres. Si ces codes sont en cours d'exécution dans Eclipse IDE ils devraient tous être en mesure de trouver le chemin d'accès du fichier, y compris l'indication de la classe et de l'ouvrir ou créer un fichier avec le chemin trouvé.
Mais il est difficile, lorsque vous exécutez l'exécutable fichier jar directement ou par l'intermédiaire de la ligne de commande, il sera a échoué car le chemin d'accès de fichier jar obtenus par les méthodes ci-dessus donnera un chemin interne dans le fichier jar, c'est qu'il donne toujours un chemin que
rsrc:projet-nom (je devrais peut-être dire que c'est le nom du package de la classe principale de fichier de la classe indiquée)
Je ne peux pas convertir le rsrc:... chemin d'accès à un chemin externe, c'est lorsque vous exécutez le fichier jar en dehors de l'IDE Eclipse, il ne peut pas obtenir le chemin d'accès du fichier jar.
La seule voie possible pour obtenir le chemin d'accès de l'exécution de fichier jar en dehors de l'IDE Eclipse est
cette ligne de code peut renvoyer le chemin de vie (y compris le nom de fichier) de la course de fichier jar (à noter que la voie de retour n'est pas le répertoire de travail), le java document et certaines personnes ont dit qu'il sera de retour les chemins d'accès de tous les fichiers dans le même répertoire, mais comme mes tests, si dans le même répertoire comprennent de nombreux fichiers jar, il ne retourne que le chemin d'accès de l'exécution de pot (sur les multiples chemins de problème en effet, c'est arrivé dans l'Éclipse).
java.class.path
peut avoir plusieurs valeurs. Un ces valeurs ne sont certainement fournir le répertoire ou le fichier JAR où la classe est situé, mais lequel?Je confirme , j'ai essayé d'autres solutions, mais ne jamais obtenir le pot de nom de fichier. Cela fonctionne très simplement ! merci +1
OriginalL'auteur phchen2
la réponse sélectionnée ci-dessus ne fonctionne pas si vous exécutez votre bocal par cliquez sur à partir de l'environnement de bureau Gnome (pas de n'importe quel script ou terminal).
Au lieu de cela, j'ai de bons que la solution suivante est de travailler partout:
Cette solution ne peut renvoyer l'emplacement de "." dans le fichier JAR, pas l'emplacement le fichier JAR.
Attention: il est recommandé de ne pas utiliser
URLDecoder
de décoder les caractères spéciaux. En particulier, des personnages comme+
sera tort décodé espaces. Voir ma réponse pour plus de détails.Au Printemps de démarrage, il va jeter
NullPointerException
Vous aurez
NPE
si il n'y a pas de ressources dans le BOCAL.OriginalL'auteur lviggiani
En fait, ici, c'est une meilleure version de la vieille un échec si un nom de dossier a un espace.
Comme pour défaut avec les applets, vous ne serait pas l'habitude d'avoir accès aux fichiers locaux de toute façon. Je ne sais pas beaucoup au sujet des témoins de jéhovah, mais pour gérer les fichiers en local, ne serait-il pas possible de télécharger l'application.?
OriginalL'auteur bacup lad
La solution la plus simple est de passer le chemin d'accès comme argument lors de l'exécution de la jarre.
Vous pouvez automatiser cela avec un script shell (.chauve-souris dans Windows, .sh n'importe où ailleurs):
J'ai utilisé
.
pour passer le répertoire de travail courant.Mise à JOUR
Vous pouvez coller le fichier jar dans un sous-répertoire de sorte que les utilisateurs ne l'avez pas accidentellement sur elle. Votre code doit également vérifier que les arguments de ligne de commande ont été fournis, et de fournir un bon message d'erreur si les arguments sont manquantes.
OriginalL'auteur Max Heiber
D'autres réponses semblent indiquer le code source qui est l'emplacement des fichiers Jar qui n'est pas un répertoire.
Utilisation
OriginalL'auteur F.O.O
J'ai dû le désordre autour d'un lot avant, j'ai enfin trouvé un travail (et court) solution.
Il est possible que le
jarLocation
est livré avec un préfixe commefile:\
oujar:file\
, qui peuvent être supprimés en utilisantString#substring()
.OriginalL'auteur Jelle
Le chemin se réfère toujours à la ressource dans le fichier jar.
String path = new File(getClass().getResource("").getPath()).getParentFile().getParent(); File jarDir = new File(path.substring(5));
Les deux
getResource("")
etgetResource(".")
échoué dans mes tests, lorsque la classe se trouvaient à l'intérieur d'un fichier JAR; les deux invocations retourné null.Ce lève
NullPointerException
.OriginalL'auteur ZZZ
Fonctionne bien sur Windows
OriginalL'auteur Denton
J'ai essayé d'obtenir le pot de course chemin à l'aide de
c:\app>java-jar application.jar
De l'exécution de l'jar application nommée "application.jar" sur Windows dans le dossier "c:\app", la valeur de la variable de Chaîne "dossier" a été "\c:\app\application.jar" et j'ai eu des problèmes de test pour le chemin de la rectitude
J'ai donc essayé de définir le "test":
pour obtenir de chemin d'accès dans un format tel que "c:\app" au lieu de "\c:\app\application.jar" et j'ai remarqué qu'il travail.
OriginalL'auteur TheGreatPsychoticBunny
Quelque chose qui est frustrant, c'est que lorsque vous êtes en développement dans Eclipse
MyClass.class.getProtectionDomain().getCodeSource().getLocation()
renvoie la/bin
répertoire qui est très bien, mais quand vous compilez pour un bocal, le chemin d'accès inclut la/myjarname.jar
partie qui vous donne illégale des noms de fichier.Pour avoir le code du travail à la fois dans l'ide et une fois qu'il est compilé pour un pot, j'utilise le bout de code suivant:
OriginalL'auteur Alexander
Pas vraiment sur les autres, mais dans mon cas ça ne fonctionne pas avec un "Runnable jar" et j'ai eu de travail en fixant les codes d'ensemble de phchen2 réponse et une autre à partir de ce lien :Comment obtenir le chemin d'accès d'un fichier JAR?
Le code:
OriginalL'auteur Fahad Alkamli
Avoir essayé plusieurs solutions là-haut, mais aucun n'a abouti à des résultats corrects pour la (probablement spécial) que le runnable jar a été exporté avec "l'Emballage des bibliothèques externes" dans Eclipse. Pour une raison que toutes les solutions basées sur la ProtectionDomain faire suite à null dans ce cas.
À partir de la combinaison de certaines des solutions ci-dessus, j'ai réussi à atteindre les objectifs suivants code de travail:
OriginalL'auteur DragonGamer
Cette méthode, appelée à partir de code dans l'archive, renvoie le dossier où le .le fichier jar est. Il faut travailler dans Windows ou Unix.
Dérivé de code: Déterminer si l'exécution de JAR
OriginalL'auteur Bacup Lad
Mentionner qu'elle n'est vérifiée que dans
Windows
mais je pense qu'il 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'une.jar
fichier pour démarrer l'autre.jar
fichier qui est dans le même répertoire.Le problème est que lorsque vous le démarrez à partir de la
cmd
le répertoire courant estsystem32
.avec le nom du dossier
;][[;'57f2g34g87-8+9-09!2#@!$%^^&()
ou()%&$%^@#
il fonctionne bien.
ProcessBuilder
avec le ci-dessous comme suit:..
getBasePathForClass(Class<?> classs)
:OriginalL'auteur GOXR3PLUS
Ce code a fonctionné pour moi:
OriginalL'auteur John Lockwood
J'écris en Java 7, et testez-le dans Windows 7 avec l'Oracle de l'exécution, et Ubuntu avec l'open source de l'exécution. Cela fonctionne parfaitement pour les systèmes:
Le chemin d'accès pour le répertoire parent de l'exécution d'un fichier jar (en supposant que la classe de l'appel de ce code est un enfant direct de l'jar archive elle-même):
Donc, le chemin de foo.jar serait:
Encore une fois, ce n'était pas testé sur un Mac ou un Windows plus ancien
OriginalL'auteur sudoBen
La
getProtectionDomain
approche pourrait ne pas fonctionner parfois, par exemple lorsque vous devez trouver le pot pour quelques-uns des principaux des classes java (e.g dans mon casStringBuilder
classe au sein d'IBM JDK), mais à l'issue fonctionne de manière transparente:OriginalL'auteur Vasu
J'ai une autre façon d'obtenir de la Chaîne à l'emplacement d'une classe.
La Chaîne de sortie sera de la forme de
Les espaces et autres caractères sont traités, et dans la forme, sans
file:/
. Ce sera plus facile à utiliser.OriginalL'auteur NoSegfault