Как получить путь к работающему файлу JAR? - PullRequest
535 голосов
/ 26 ноября 2008

Мой код выполняется внутри JAR-файла, скажем, foo.jar, и мне нужно знать, в коде, в какой папке находится запущенный foo.jar.

Итак, если foo.jar находится в C:\FOO\, я хочу получить этот путь независимо от того, какой у меня текущий рабочий каталог.

Ответы [ 27 ]

4 голосов
/ 28 сентября 2011

выбранный выше ответ не работает, если вы запустили свой jar-файл, щелкнув по нему в среде рабочего стола Gnome (не в сценарии или терминале).

Вместо этого мне нравится, что везде работает следующее решение:

    try {
        return URLDecoder.decode(ClassLoader.getSystemClassLoader().getResource(".").getPath(), "UTF-8");
    } catch (UnsupportedEncodingException e) {
        return "";
    }
3 голосов
/ 10 июня 2016

Другие ответы указывают на источник кода, который является местоположением файла Jar, а не каталогом.

Используйте

return new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath()).getParentFile();
3 голосов
/ 30 августа 2016

Мне пришлось много возиться, прежде чем я наконец нашел рабочее (и короткое) решение.
Возможно, что jarLocation имеет префикс типа file:\ или jar:file\, который можно удалить с помощью String#substring().

URL jarLocationUrl = MyClass.class.getProtectionDomain().getCodeSource().getLocation();
String jarLocation = new File(jarLocationUrl.toString()).getParent();
3 голосов
/ 20 октября 2015

Самое простое решение - передать путь в качестве аргумента при запуске jar.

Вы можете автоматизировать это с помощью сценария оболочки (.bat в Windows, .sh где-либо еще):

java -jar my-jar.jar .

Я использовал . для передачи текущего рабочего каталога.

UPDATE

Возможно, вы захотите вставить файл jar в подкаталог, чтобы пользователи случайно не щелкали по нему. Ваш код должен также проверить, чтобы убедиться, что аргументы командной строки были предоставлены, и предоставить хорошее сообщение об ошибке, если аргументы отсутствуют.

3 голосов
/ 15 апреля 2011

На самом деле вот лучшая версия - старая не удалась, если в имени папки был пробел.

  private String getJarFolder() {
    // get name and path
    String name = getClass().getName().replace('.', '/');
    name = getClass().getResource("/" + name + ".class").toString();
    // remove junk
    name = name.substring(0, name.indexOf(".jar"));
    name = name.substring(name.lastIndexOf(':')-1, name.lastIndexOf('/')+1).replace('%', ' ');
    // remove escape characters
    String s = "";
    for (int k=0; k<name.length(); k++) {
      s += name.charAt(k);
      if (name.charAt(k) == ' ') k += 2;
    }
    // replace '/' with system separator char
    return s.replace('/', File.separatorChar);
  }

Что касается неудачи с апплетами, у вас все равно обычно не будет доступа к локальным файлам. Я не очень разбираюсь в JWS, но для обработки локальных файлов может оказаться невозможным загрузить приложение .?

2 голосов
/ 21 февраля 2014

Я попытался получить путь бега банки, используя

String folder = MyClassName.class.getProtectionDomain().getCodeSource().getLocation().getPath();

c: \ app> java -jar application.jar

При запуске приложения jar с именем «application.jar» в Windows в папке « c: \ app » значение строковой переменной «folder» было « \ c: \». app \ application.jar"и у меня возникли проблемы с проверкой правильности пути

File test = new File(folder);
if(file.isDirectory() && file.canRead()) { //always false }

Итак, я попытался определить «тест» как:

String fold= new File(folder).getParentFile().getPath()
File test = new File(fold);

чтобы получить путь в правильном формате, например " c: \ app " вместо " \ c: \ app \ application.jar ", и я заметил, что он работает.

2 голосов
/ 16 ноября 2010
String path = getClass().getResource("").getPath();

Путь всегда относится к ресурсу в файле jar.

2 голосов
/ 05 апреля 2013
public static String dir() throws URISyntaxException
{
    URI path=Main.class.getProtectionDomain().getCodeSource().getLocation().toURI();
    String name= Main.class.getPackage().getName()+".jar";
    String path2 = path.getRawPath();
    path2=path2.substring(1);

    if (path2.contains(".jar"))
    {
        path2=path2.replace(name, "");
    }
    return path2;}

Хорошо работает на Windows

1 голос
/ 21 марта 2019

Опробовали несколько решений, но ни одно из них не дало правильных результатов для (вероятно, особого) случая, когда исполняемый файл jar был экспортирован с "Упаковкой внешних библиотек" в Eclipse. По какой-то причине все решения, основанные на ProtectionDomain, в этом случае приводят к нулю.

Сочетая некоторые решения выше, мне удалось получить следующий рабочий код:

String surroundingJar = null;

// gets the path to the jar file if it exists; or the "bin" directory if calling from Eclipse
String jarDir = new File(ClassLoader.getSystemClassLoader().getResource(".").getPath()).getAbsolutePath();

// gets the "bin" directory if calling from eclipse or the name of the .jar file alone (without its path)
String jarFileFromSys = System.getProperty("java.class.path").split(";")[0];

// If both are equal that means it is running from an IDE like Eclipse
if (jarFileFromSys.equals(jarDir))
{
    System.out.println("RUNNING FROM IDE!");
    // The path to the jar is the "bin" directory in that case because there is no actual .jar file.
    surroundingJar = jarDir;
}
else
{
    // Combining the path and the name of the .jar file to achieve the final result
    surroundingJar = jarDir + jarFileFromSys.substring(1);
}

System.out.println("JAR File: " + surroundingJar);
1 голос
/ 21 июня 2016

Не совсем уверен насчет других, но в моем случае это не сработало с «Runnable jar», и я получил его, исправив коды вместе из ответа phchen2 и другого по этой ссылке: Как получить путь запущенного файла JAR? Код:

               String path=new java.io.File(Server.class.getProtectionDomain()
                .getCodeSource()
                .getLocation()
                .getPath())
          .getAbsolutePath();
       path=path.substring(0, path.lastIndexOf("."));
       path=path+System.getProperty("java.class.path");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...