Мой код работает внутри файла JAR, скажем, foo.jar , и мне нужно знать, в коде, в какой папке находится запущенный файл foo.jar .
Так что, если foo.jar находится в C:\FOO\
, я хочу получить этот путь независимо от того, каков мой текущий рабочий каталог.
java
path
jar
executable-jar
Тьяго Чавес
источник
источник
Ответы:
Замените «MyClass» на имя вашего класса.
Очевидно, это будет делать странные вещи, если ваш класс был загружен из не файлового местоположения.
источник
toURI()
шаг жизненно необходим, чтобы избежать проблем со специальными символами, включая пробелы и плюсы Правильный однострочный:return new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().toURI());
использованиеURLDecoder
не работает для многих специальных символов. Смотрите мой ответ ниже для более подробной информации.getProtectionDomain
имеет значение null, если вы получаете свой класс от трассировки:val strace = Thread.currentThread().getStackTrace; val path = strace(1).getClass.getProtectionDomain
Лучшее решение для меня:
Это должно решить проблему с пробелами и специальными символами.
источник
URLDecoder.decode(ClassLoader.getSystemClassLoader().getResource(".").getPath(), "UTF-8");
) в Linux. Тем не менее, я не пробовал на Windows.URLDecoder
для декодирования специальных символов. В частности, символы like+
будут ошибочно декодированы в пробелы. Смотрите мой ответ для деталей.Чтобы получить
File
для данногоClass
, есть два шага:Class
в аURL
URL
в аFile
Важно понимать оба шага, а не объединять их.
Если у вас есть
File
, вы можете позвонить,getParentFile
чтобы получить содержащую папку, если это то, что вам нужно.Шаг 1:
Class
вURL
Как обсуждалось в других ответах, есть два основных способа найти
URL
отношение кClass
.URL url = Bar.class.getProtectionDomain().getCodeSource().getLocation();
URL url = Bar.class.getResource(Bar.class.getSimpleName() + ".class");
У обоих есть плюсы и минусы.
getProtectionDomain
Подход дает основание расположение класса (например, содержащий JAR - файл). Однако, возможно, что политика безопасности среды выполнения Java сработаетSecurityException
при вызовеgetProtectionDomain()
, поэтому, если ваше приложение должно работать в различных средах, лучше всего протестировать во всех них.getResource
Подход дает полный путь URL ресурса класса, из которого вам нужно будет выполнить дополнительные манипуляции со строками. Это может бытьfile:
путь, но он также может бытьjar:file:
или даже чем-то более неприятнымbundleresource://346.fwk2106232034:4/foo/Bar.class
при выполнении в рамках OSGi. И наоборот,getProtectionDomain
подход правильно даетfile:
URL, даже из OSGi.Обратите внимание, что оба
getResource("")
иgetResource(".")
потерпели неудачу в моих тестах, когда класс находился в файле JAR; оба вызова вернули ноль. Поэтому я рекомендую вызов №2, показанный выше, так как он кажется более безопасным.Шаг 2:
URL
чтобыFile
В любом случае, если у вас есть
URL
, следующим шагом будет преобразование вFile
. Это его собственная проблема; см. подробности в блоге Kohsuke Kawaguchi об этом , но вкратце вы можете использовать его,new File(url.toURI())
если URL-адрес полностью сформирован.Наконец, я бы очень не рекомендовал использовать
URLDecoder
. Некоторые персонажи URL,:
и ,/
в частности, не являются допустимыми URL-кодированных символов. От URLDecoder Javadoc:На практике,
URLDecoder
как правило, не бросать,IllegalArgumentException
как угрожали выше. И если ваш путь к файлу имеет пробелы, закодированные как%20
, этот подход может работать. Однако, если в вашем пути к файлу есть другие не алфавитные символы, например, у+
вас будут проблемы сURLDecoder
указанием пути к файлу.Рабочий код
Для выполнения этих шагов у вас могут быть такие методы:
Вы можете найти эти методы в общей библиотеке SciJava :
источник
Вы также можете использовать:
источник
Используйте ClassLoader.getResource (), чтобы найти URL для вашего текущего класса.
Например:
(Этот пример взят из аналогичного вопроса .)
Чтобы найти каталог, вам необходимо вручную разобрать URL. См. Учебник JarClassLoader для формата jar URL.
источник
NPE
потому что вы не ответили на вопрос, который был задан (был задан путь к директории JAR, и вы ответили на совершенно другой вопрос: путь к классу). 2. Как указали другие, и у меня возникла та же проблема, она не работает для апплетов. 3. Возвращается путь не канонического представления пути вообще:jar:file:/listener/build/libs/listener-1.0.0-all.jar!/shared/Test.class
.Я удивлен, увидев, что никто недавно не предложил использовать
Path
. Далее следует цитата: « класс включает в себя различные методы , которые могут быть использованы для получения информации о пути, элементы доступа пути, преобразовать путь к другим формам, или экстракт порциям по пути »Path
Таким образом, хорошая альтернатива - получить
Path
объект как:источник
Единственное решение, которое работает для меня на Linux, Mac и Windows:
источник
У меня была та же проблема, и я решил ее так:
Надеюсь, я вам помог.
источник
Вот обновление до других комментариев, которые кажутся мне неполными из-за специфики
источник
URLDecoder
для декодирования специальных символов. В частности, символы like+
будут ошибочно декодированы в пробелы. Смотрите мой ответ для деталей.URLDecoder
несмотря на свое имя, предназначен для декодирования URL и имен и значений параметров формы, а не URL.Для получения пути запуска jar-файла я изучил вышеупомянутые решения и перепробовал все методы, которые существуют между собой. Если этот код выполняется в Eclipse IDE, все они должны иметь возможность найти путь к файлу, включая указанный класс, и открыть или создать указанный файл с найденным путем.
Но это сложно, если запустить файл jar, работающий под управлением, напрямую или через командную строку, он потерпит неудачу, так как путь к файлу jar, полученный из вышеуказанных методов, даст внутренний путь в файле jar, то есть он всегда дает путь в виде
rsrc: имя-проекта (возможно, я должен сказать, что это имя пакета файла основного класса - указанный класс)
Я не могу преобразовать путь rsrc: ... во внешний путь, то есть при запуске файла JAR вне Eclipse IDE он не может получить путь к файлу JAR.
Единственный возможный способ получить путь запуска jar-файла вне Eclipse IDE - это
эта строка кода может возвращать живой путь (включая имя файла) запущенного файла JAR (обратите внимание, что путь возврата не является рабочим каталогом), как документ Java, и некоторые люди сказали, что он вернет пути всех файлов классов в том же каталоге, но, как и в моих тестах, если в одном и том же каталоге содержится много файлов jar, он только возвращает путь запуска jar (действительно, проблема с несколькими путями произошла в Eclipse).
источник
java.class.path
может быть многозначным. Одно из этих значений, безусловно, обеспечит каталог или JAR-файл, в котором находится текущий класс, но какой именно?Другие ответы, кажется, указывают на источник кода, который является местоположением файла Jar, который не является каталогом.
использование
источник
выбранный выше ответ не работает, если вы запустите свой jar-файл, щелкнув по нему в среде рабочего стола Gnome (а не в любом скрипте или терминале).
Вместо этого мне понравилось, что следующее решение работает везде:
источник
URLDecoder
для декодирования специальных символов. В частности, символы like+
будут ошибочно декодированы в пробелы. Смотрите мой ответ для деталей.NullPointerException
NPE
если в JAR нет ресурсов.На самом деле вот лучшая версия - старая не удалась, если в имени папки был пробел.
Что касается неудачи с апплетами, у вас все равно обычно не будет доступа к локальным файлам. Я не знаю много о JWS, но для обработки локальных файлов может быть невозможно загрузить приложение.
источник
Я попытался получить путь кувшина с помощью
c: \ app> java -jar application.jar
Запустив jar-приложение с именем «application.jar», в Windows в папке « c: \ app » значение строковой переменной «folder» было « \ c: \ app \ application.jar », и у меня были проблемы с тестированием для правильность пути
Поэтому я попытался определить «тест» как:
чтобы получить путь в правильном формате, например, « c: \ app » вместо « \ c: \ app \ application.jar », и я заметил, что он работает.
источник
Самое простое решение - передать путь в качестве аргумента при запуске фляги.
Вы можете автоматизировать это с помощью сценария оболочки (.bat в Windows, .sh в любом другом месте):
Я использовал
.
для передачи текущего рабочего каталога.ОБНОВИТЬ
Возможно, вы захотите вставить файл JAR в подкаталог, чтобы пользователи случайно не щелкали по нему. Ваш код должен также проверить, чтобы убедиться, что аргументы командной строки были предоставлены, и предоставить хорошее сообщение об ошибке, если аргументы отсутствуют.
источник
Мне пришлось много возиться, прежде чем я наконец нашел рабочее (и короткое) решение.
Вполне возможно, что
jarLocation
идет с префиксом вродеfile:\
илиjar:file\
, который можно удалить с помощьюString#substring()
.источник
Путь всегда относится к ресурсу в файле jar.
источник
String path = new File(getClass().getResource("").getPath()).getParentFile().getParent(); File jarDir = new File(path.substring(5));
getResource("")
и другоеgetResource(".")
не удалось в моих тестах, когда класс находился в файле JAR; оба вызова вернули ноль.NullPointerException
.Хорошо работает на Windows
источник
Что разочаровывает, так это то, что когда вы разрабатываете в Eclipse,
MyClass.class.getProtectionDomain().getCodeSource().getLocation()
возвращается/bin
каталог, который великолепен, но когда вы компилируете его в jar, путь включает в себя/myjarname.jar
часть, которая дает вам недопустимые имена файлов.Чтобы код работал как в ide, так и после его компиляции в jar, я использую следующий фрагмент кода:
источник
Не совсем уверен насчет других, но в моем случае это не сработало с «Runnable jar», и я получил его, скомбинировав коды из ответа phchen2 и другого по этой ссылке: Как получить путь к работающему файлу JAR? Код:
источник
Опробовали несколько решений, но ни одно из них не дало правильных результатов для (вероятно, особого) случая, когда исполняемый файл jar был экспортирован с помощью «Упаковки внешних библиотек» в Eclipse. По какой-то причине все решения, основанные на ProtectionDomain, в этом случае приводят к нулю.
Комбинируя некоторые решения выше, мне удалось получить следующий рабочий код:
источник
Попробуй это:
источник
Этот метод, вызываемый из кода в архиве, возвращает папку, в которой находится файл .jar. Он должен работать в Windows или Unix.
Получено из кода в: Определите, работает ли из JAR
источник
Стоит упомянуть, что это только проверено,
Windows
но я думаю, что оно отлично работает на других операционных системах [Linux,MacOs,Solaris
] :).У меня было 2
.jar
файла в одном каталоге. Я хотел из одного.jar
файла запустить другой.jar
файл, который находится в том же каталоге.Проблема в том, что при запуске его из
cmd
текущего каталога естьsystem32
.;][[;'57f2g34g87-8+9-09!2#@!$%^^&()
или()%&$%^@#
он работает хорошо.ProcessBuilder
с ниже следующим:🍂 ..
🍂
getBasePathForClass(Class<?> classs)
:источник
Этот код работал для меня:
источник
Этот код помог мне определить, выполняется ли программа внутри файла JAR или IDE:
Если мне нужно получить полный путь к файлу JAR для Windows, я использую этот метод:
Мой полный код, работающий с приложением Spring Boot с использованием
CommandLineRunner
реализации, чтобы приложение всегда выполнялось в представлении консоли (Двойной щелчок по ошибке в имени файла JAR), я использую следующий код:источник
Я пишу на Java 7 и тестирую в Windows 7 со средой исполнения Oracle и Ubuntu со средой исполнения с открытым исходным кодом. Это прекрасно работает для этих систем:
Путь к родительскому каталогу любого работающего файла jar (при условии, что класс, вызывающий этот код, является прямым потомком самого архива jar):
Итак, путь к foo.jar будет:
Опять же, это не было проверено ни на одном Mac или более старой Windows
источник
Этот
getProtectionDomain
подход иногда может не сработать, например, когда вам нужно найти jar для некоторых основных java-классов (например, в моемStringBuilder
классе case в IBM JDK), однако следующее работает без проблем:источник
У меня есть другой способ получить расположение класса String.
Выходная строка будет иметь вид
Пробелы и другие символы обрабатываются и в форме без
file:/
. Так будет проще в использовании.источник