Jak uzyskać ścieżkę uruchomionego pliku JAR?

Mój kod jest w pliku JAR, powiedzmy foo.jar, i muszę wiedzieć, w kodzie, w którym folderze działa foo.jar jest.

Więc, jeśli foo.jar jest w C:\FOO\, chcę uzyskać tę ścieżkę bez względu na to, jaki jest mój bieżący katalog roboczy.

Author: informatik01, 2008-11-26

29 answers

return new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().toURI()).getPath();

Zastąp "MyClass" nazwą twojej klasy

Oczywiście, to zrobi dziwne rzeczy, jeśli klasa została załadowana z lokalizacji spoza pliku.

 458
Author: Zarkonnen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-12 21:53:13

Najlepsze rozwiązanie dla mnie:

String path = Test.class.getProtectionDomain().getCodeSource().getLocation().getPath();
String decodedPath = URLDecoder.decode(path, "UTF-8");

Powinno to rozwiązać problem ze spacjami i znakami specjalnymi.

 177
Author: Fab,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-12 13:12:24

Aby uzyskać File dla danego Class, są dwa kroki:

  1. Konwertuj Class na URL
  2. Konwertuj URL na File
Ważne jest, aby zrozumieć oba kroki i nie łączyć ich ze sobą.

Gdy już masz File, możesz wywołać getParentFile, aby uzyskać folder zawierający, jeśli tego potrzebujesz.

Krok 1: Class do URL

Jak wspomniano w innych odpowiedziach, istnieją dwa główne sposoby, aby znaleźć URL istotne dla Class.

  1. URL url = Bar.class.getProtectionDomain().getCodeSource().getLocation();

  2. URL url = Bar.class.getResource(Bar.class.getSimpleName() + ".class");

Oba mają plusy i minusy.

Podejście getProtectionDomain daje podstawową lokalizację klasy (np. plik zawierający JAR). Jest jednak możliwe, że polityka bezpieczeństwa środowiska Java runtime rzuci {[16] } podczas wywoływania getProtectionDomain(), więc jeśli aplikacja musi działać w różnych środowiskach, najlepiej przetestować ją we wszystkich.

Podejście getResource daje pełną ścieżkę zasobu URL klasa, z której będziesz musiał wykonać dodatkową manipulację ciągiem. Może to być ścieżka file:, ale może to być również ścieżka jar:file: lub nawet coś straszniejszego jak bundleresource://346.fwk2106232034:4/foo/Bar.class podczas wykonywania w ramach frameworka OSGi. I odwrotnie, podejście getProtectionDomain poprawnie wyświetla adres URL file: nawet z poziomu OSGi.

Zauważ, że zarówno getResource("") jak i getResource(".") nie powiodły się w moich testach, gdy Klasa znajdowała się w pliku JAR; oba wywołania zwracały null. Polecam więc pokazaną powyżej inwokację #2, jako że wydaje się bezpieczniejsze.

Krok 2: URL do File

Tak czy inaczej, gdy masz URL, następnym krokiem jest konwersja na File. To jest jego własne wyzwanie; zobacz kohsuke Kawaguchi na blogu o tym, aby uzyskać szczegółowe informacje, ale krótko mówiąc, możesz użyć new File(url.toURI()), o ile adres URL jest całkowicie dobrze uformowany.

Na koniec chciałbym mocno zniechęcić do używania URLDecoder. Niektóre znaki adresu URL, w szczególności : i /, nie są poprawnymi znakami zakodowanymi w URL. Z URLDecoder Javadoc:

Zakłada się, że wszystkie znaki w zakodowanym łańcuchu są jednym z następujących znaków: "a" przez "z", " a "przez " Z", " 0 "przez" 9 " oraz "-", "_", ".", oraz"*". Znak " % " jest dozwolony, ale jest interpretowany jako początek specjalnej sekwencji ucieczki.

...

Są dwa możliwe sposoby, w jaki Dekoder może radzić sobie z nielegalnymi ciągami. To może albo zostawić nielegalnych znaków w spokoju lub może rzucić Nielegalargumentexception. Jakie podejście przyjmuje dekoder pozostaje do realizacji.

W praktyce URLDecoder generalnie nie rzuca IllegalArgumentException Jak wyżej. Jeśli ścieżka do pliku ma spacje zakodowane jako %20, takie podejście może wydawać się skuteczne. Jeśli jednak ścieżka do pliku zawiera inne znaki niealfameryczne, takie jak +, będziesz miał problemy z zniekształceniem ścieżki do pliku.

Kodeks Pracy

Aby osiągnąć te kroki, możesz mieć metody takie jak następujące:

/**
 * Gets the base location of the given class.
 * <p>
 * If the class is directly on the file system (e.g.,
 * "/path/to/my/package/MyClass.class") then it will return the base directory
 * (e.g., "file:/path/to").
 * </p>
 * <p>
 * If the class is within a JAR file (e.g.,
 * "/path/to/my-jar.jar!/my/package/MyClass.class") then it will return the
 * path to the JAR (e.g., "file:/path/to/my-jar.jar").
 * </p>
 *
 * @param c The class whose location is desired.
 * @see FileUtils#urlToFile(URL) to convert the result to a {@link File}.
 */
public static URL getLocation(final Class<?> c) {
    if (c == null) return null; // could not load the class

    // try the easy way first
    try {
        final URL codeSourceLocation =
            c.getProtectionDomain().getCodeSource().getLocation();
        if (codeSourceLocation != null) return codeSourceLocation;
    }
    catch (final SecurityException e) {
        // NB: Cannot access protection domain.
    }
    catch (final NullPointerException e) {
        // NB: Protection domain or code source is null.
    }

    // NB: The easy way failed, so we try the hard way. We ask for the class
    // itself as a resource, then strip the class's path from the URL string,
    // leaving the base path.

    // get the class's raw resource path
    final URL classResource = c.getResource(c.getSimpleName() + ".class");
    if (classResource == null) return null; // cannot find class resource

    final String url = classResource.toString();
    final String suffix = c.getCanonicalName().replace('.', '/') + ".class";
    if (!url.endsWith(suffix)) return null; // weird URL

    // strip the class's path from the URL string
    final String base = url.substring(0, url.length() - suffix.length());

    String path = base;

    // remove the "jar:" prefix and "!/" suffix, if present
    if (path.startsWith("jar:")) path = path.substring(4, path.length() - 2);

    try {
        return new URL(path);
    }
    catch (final MalformedURLException e) {
        e.printStackTrace();
        return null;
    }
} 

/**
 * Converts the given {@link URL} to its corresponding {@link File}.
 * <p>
 * This method is similar to calling {@code new File(url.toURI())} except that
 * it also handles "jar:file:" URLs, returning the path to the JAR file.
 * </p>
 * 
 * @param url The URL to convert.
 * @return A file path suitable for use with e.g. {@link FileInputStream}
 * @throws IllegalArgumentException if the URL does not correspond to a file.
 */
public static File urlToFile(final URL url) {
    return url == null ? null : urlToFile(url.toString());
}

/**
 * Converts the given URL string to its corresponding {@link File}.
 * 
 * @param url The URL to convert.
 * @return A file path suitable for use with e.g. {@link FileInputStream}
 * @throws IllegalArgumentException if the URL does not correspond to a file.
 */
public static File urlToFile(final String url) {
    String path = url;
    if (path.startsWith("jar:")) {
        // remove "jar:" prefix and "!/" suffix
        final int index = path.indexOf("!/");
        path = path.substring(4, index);
    }
    try {
        if (PlatformUtils.isWindows() && path.matches("file:[A-Za-z]:.*")) {
            path = "file:/" + path.substring(5);
        }
        return new File(new URL(path).toURI());
    }
    catch (final MalformedURLException e) {
        // NB: URL is not completely well-formed.
    }
    catch (final URISyntaxException e) {
        // NB: URL is not completely well-formed.
    }
    if (path.startsWith("file:")) {
        // pass through the URL as-is, minus "file:" prefix
        path = path.substring(5);
        return new File(path);
    }
    throw new IllegalArgumentException("Invalid URL: " + url);
}

Możesz znaleźć te metody w SciJava Common biblioteka:

 138
Author: ctrueden,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-28 19:31:56

Możesz również użyć:

CodeSource codeSource = YourMainClass.class.getProtectionDomain().getCodeSource();
File jarFile = new File(codeSource.getLocation().toURI().getPath());
String jarDir = jarFile.getParentFile().getPath();
 47
Author: Benny Neugebauer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-04 22:49:54

Użyj Classloadera.getResource (), aby znaleźć adres URL dla bieżącej klasy.

Na przykład:

package foo;

public class Test
{
    public static void main(String[] args)
    {
        ClassLoader loader = Test.class.getClassLoader();
        System.out.println(loader.getResource("foo/Test.class"));
    }
}

(Ten przykład zaczerpnięty z podobnego pytania .)

Aby znaleźć katalog, musisz ręcznie rozdzielić adres URL. Format adresu URL jar można znaleźć w samouczku JarClassLoader.

 23
Author: Jon Skeet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:33:26

Jestem zaskoczony, widząc, że nikt ostatnio nie zaproponował użycia Path. Poniżej znajduje się cytat: "klasa Path zawiera różne metody, które mogą być użyte do uzyskania informacji o ścieżce, dostępu do elementów ścieżki, konwersji ścieżki do innych form lub wyodrębnienia fragmentów ścieżki "

Tak więc, dobrą alternatywą jest uzyskanie Path objest jako:

Path path = Paths.get(Test.class.getProtectionDomain().getCodeSource().getLocation().toURI());
 16
Author: mat_boy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-28 12:53:00

Jedyne rozwiązanie, które działa dla mnie na Linuksie, Mac i Windows:

public static String getJarContainingFolder(Class aclass) throws Exception {
  CodeSource codeSource = aclass.getProtectionDomain().getCodeSource();

  File jarFile;

  if (codeSource.getLocation() != null) {
    jarFile = new File(codeSource.getLocation().toURI());
  }
  else {
    String path = aclass.getResource(aclass.getSimpleName() + ".class").getPath();
    String jarFilePath = path.substring(path.indexOf(":") + 1, path.indexOf("!"));
    jarFilePath = URLDecoder.decode(jarFilePath, "UTF-8");
    jarFile = new File(jarFilePath);
  }
  return jarFile.getParentFile().getAbsolutePath();
}
 13
Author: Dmitry Trofimov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-20 17:41:55

Miałem ten sam problem i rozwiązałem go w ten sposób:

File currentJavaJarFile = new File(Main.class.getProtectionDomain().getCodeSource().getLocation().getPath());   
String currentJavaJarFilePath = currentJavaJarFile.getAbsolutePath();
String currentRootDirectoryPath = currentJavaJarFilePath.replace(currentJavaJarFile.getName(), "");
Mam nadzieję, że ci pomogłem.
 6
Author: Charlie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-12 07:33:36

Oto uaktualnienie do innych komentarzy, które wydają mi się niekompletne dla specyfiki

Używanie względnego "folderu" na zewnątrz .plik jar (w tym samym jar "lokalizacja": {]}

String path = 
  YourMainClassName.class.getProtectionDomain().
  getCodeSource().getLocation().getPath();

path = 
  URLDecoder.decode(
    path, 
    "UTF-8");

BufferedImage img = 
  ImageIO.read(
    new File((
        new File(path).getParentFile().getPath()) +  
        File.separator + 
        "folder" + 
        File.separator + 
        "yourfile.jpg"));
 6
Author: Zon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-05 16:43:38

Wybrana powyżej odpowiedź nie działa, jeśli uruchomisz swój jar klikając na niego ze środowiska graficznego Gnome (nie ze skryptu lub terminala).

Zamiast tego, mam sentyment, że następujące rozwiązanie działa wszędzie:

    try {
        return URLDecoder.decode(ClassLoader.getSystemClassLoader().getResource(".").getPath(), "UTF-8");
    } catch (UnsupportedEncodingException e) {
        return "";
    }
 5
Author: lviggiani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-28 08:18:58

Aby uzyskać ścieżkę uruchomienia pliku jar, przestudiowałem powyższe rozwiązania i wypróbowałem wszystkie metody, które istnieją pewne różnice między sobą. Jeśli kod ten jest uruchomiony w Eclipse IDE, wszystkie powinny być w stanie znaleźć ścieżkę do pliku wraz ze wskazaną klasą i otworzyć lub utworzyć wskazany plik ze znalezioną ścieżką.

Ale jest to trudne, gdy uruchamiamy plik JAR bezpośrednio lub za pomocą linii poleceń, nie uda się, ponieważ ścieżka pliku JAR została pobrana z powyższych metod da wewnętrzną ścieżkę w pliku jar, czyli zawsze podaje ścieżkę jako

Rsrc: project-name (może powinienem powiedzieć, że jest to nazwa pakietu głównego pliku klasy - wskazanej klasy)

Nie mogę przekonwertować RSRC:... ścieżka do zewnętrznej ścieżki, czyli gdy uruchamiamy plik JAR poza IDE Eclipse, nie możemy uzyskać ścieżki do pliku jar.

Jedynym możliwym sposobem uzyskania ścieżki do pliku JAR poza Eclipse IDE jest

System.getProperty("java.class.path")

Ten wiersz kodu może zwraca żywą ścieżkę (w tym nazwę pliku) uruchomionego pliku jar (zauważ, że ścieżka powrotna nie jest katalogiem roboczym), ponieważ dokument java i niektórzy ludzie mówili, że zwróci ścieżki wszystkich plików klas w tym samym katalogu, ale ponieważ moje testy, jeśli w tym samym katalogu znajduje się wiele plików jar, zwraca tylko ścieżkę uruchomionego jar (o problemie z wieloma ścieżkami rzeczywiście stało się to w Eclipse).

 5
Author: phchen2,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-11 12:00:41

W rzeczywistości jest to lepsza wersja-stara nie powiodła się, jeśli nazwa folderu miała spację.

  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);
  }

Jeśli chodzi o awarię z apletami, Zwykle i tak nie miałbyś dostępu do plików lokalnych. Nie wiem zbyt wiele o JWS, ale do obsługi plików lokalnych może nie być możliwe, aby pobrać aplikację.?

 3
Author: bacup lad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-15 16:43:29
String path = getClass().getResource("").getPath();

Ścieżka zawsze odnosi się do zasobu w pliku jar.

 3
Author: ZZZ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-18 06:14:21

Najprostszym rozwiązaniem jest podanie ścieżki jako argumentu podczas uruchamiania jar.

Możesz to zautomatyzować za pomocą skryptu powłoki (.nietoperz w Windows,. sh gdzie indziej):

java -jar my-jar.jar .

Użyłem . aby przekazać bieżący katalog roboczy.

UPDATE

Możesz umieścić plik jar w podkatalogu, aby użytkownicy nie kliknęli go przypadkowo. Twój kod powinien również sprawdzić, czy argumenty linii poleceń zostały podane, i podać dobry błąd wiadomość, jeśli brakuje argumentów.

 3
Author: Max Heiber,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-30 19:50:38

Inne odpowiedzi wydają się wskazywać na źródło kodu, które jest lokalizacją pliku Jar, a nie katalogiem.

Użyj

return new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath()).getParentFile();
 3
Author: F.O.O,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-10 11:57:39

Musiałem dużo pogrywać, zanim w końcu znalazłem działające (i krótkie) rozwiązanie.
Możliwe, że jarLocation ma prefiks podobny do file:\ lub jar:file\, który można usunąć za pomocą String#substring().

URL jarLocationUrl = MyClass.class.getProtectionDomain().getCodeSource().getLocation();
String jarLocation = new File(jarLocationUrl.toString()).getParent();
 3
Author: Jelle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-30 13:58:45
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;}

Działa dobrze na Windows

 2
Author: Denton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-05 10:09:48

Próbowałem uruchomić ścieżkę jar używając

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

c:\app > aplikacji java - jar.jar

Uruchomienie aplikacji jar o nazwie " application.jar", na Windows w folderze " c:\app ", wartość zmiennej łańcuchowej "folder" to " \c:\app\application.jar " i miałem problemy z testowaniem poprawności ścieżki

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

Więc próbowałem zdefiniować "test" jako:

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

Aby uzyskać ścieżkę w odpowiednim formacie, takim jak " c:\app " zamiast "\c:\app\application.jar " i zauważyłem, że działa.

 2
Author: TheGreatPsychoticBunny,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-21 15:23:28

Frustrujące jest to, że podczas tworzenia w Eclipse MyClass.class.getProtectionDomain().getCodeSource().getLocation() zwraca /bin katalog, który jest świetny, ale kiedy kompilujesz go do jar, ścieżka zawiera /myjarname.jar część, która daje nielegalne nazwy plików.

Aby kod działał zarówno w ide, jak i po jego skompilowaniu do jar, używam następującego fragmentu kodu:

URL applicationRootPathURL = getClass().getProtectionDomain().getCodeSource().getLocation();
File applicationRootPath = new File(applicationRootPathURL.getPath());
File myFile;
if(applicationRootPath.isDirectory()){
    myFile = new File(applicationRootPath, "filename");
}
else{
    myFile = new File(applicationRootPath.getParentFile(), "filename");
}
 1
Author: Alexander,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-14 06:34:54

Nie jestem pewien co do innych, ale w moim przypadku nie działało to z "Runnable jar" i udało mi się naprawić kod z odpowiedzi phchen2 i innego z tego linku: Jak uzyskać ścieżkę do uruchomionego pliku JAR? Kod:

               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");
 1
Author: Fahad Alkamli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:59

Ta metoda, wywołana z kodu w archiwum, zwraca folder, w którymplik jar jest. Powinien działać w systemie Windows lub Unix.


  private String getJarFolder() {
    String name = this.getClass().getName().replace('.', '/');
    String s = this.getClass().getResource("/" + name + ".class").toString();
    s = s.replace('/', File.separatorChar);
    s = s.substring(0, s.indexOf(".jar")+4);
    s = s.substring(s.lastIndexOf(':')-1);
    return s.substring(0, s.lastIndexOf(File.separatorChar)+1);
  } 

Pochodzi z kodu at: Określa czy działa z JAR

 0
Author: Bacup Lad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-19 13:10:19

Wspomnij, że jest sprawdzany tylko w Windows, ale myślę, że działa idealnie na innych systemach operacyjnych[Linux,MacOs,Solaris] :).


Miałem 2 .jar pliki w tym samym katalogu . Chciałem z jednego pliku .jar uruchomić drugi plik .jar, który znajduje się w tym samym katalogu.

Problem polega na tym, że po uruchomieniu z cmd bieżącym katalogiem jest system32.


Ostrzeżenia!

  • poniżej wydaje się działać całkiem dobrze we wszystkich testach zrobiłem nawet z nazwą folderu ;][[;'57f2g34g87-8+9-09!2#@!$%^^&() lub ()%&$%^@# działa dobrze.
  • używam ProcessBuilder z poniższym jak poniżej:

..

//The class from which i called this was the class `Main`
String path = getBasePathForClass(Main.class);
String applicationPath=  new File(path + "application.jar").getAbsolutePath();


System.out.println("Directory Path is : "+applicationPath);

//Your know try catch here
//Mention that sometimes it doesn't work for example with folder `;][[;'57f2g34g87-8+9-09!2#@!$%^^&()` 
ProcessBuilder builder = new ProcessBuilder("java", "-jar", applicationPath);
builder.redirectErrorStream(true);
Process process = builder.start();

//...code

getBasePathForClass(Class<?> classs):

    /**
     * Returns the absolute path of the current directory in which the given
     * class
     * file is.
     * 
     * @param classs
     * @return The absolute path of the current directory in which the class
     *         file is.
     * @author GOXR3PLUS[StackOverFlow user] + bachden [StackOverFlow user]
     */
    public static final String getBasePathForClass(Class<?> classs) {

        // Local variables
        File file;
        String basePath = "";
        boolean failed = false;

        // Let's give a first try
        try {
            file = new File(classs.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());

            if (file.isFile() || file.getPath().endsWith(".jar") || file.getPath().endsWith(".zip")) {
                basePath = file.getParent();
            } else {
                basePath = file.getPath();
            }
        } catch (URISyntaxException ex) {
            failed = true;
            Logger.getLogger(classs.getName()).log(Level.WARNING,
                    "Cannot firgue out base path for class with way (1): ", ex);
        }

        // The above failed?
        if (failed) {
            try {
                file = new File(classs.getClassLoader().getResource("").toURI().getPath());
                basePath = file.getAbsolutePath();

                // the below is for testing purposes...
                // starts with File.separator?
                // String l = local.replaceFirst("[" + File.separator +
                // "/\\\\]", "")
            } catch (URISyntaxException ex) {
                Logger.getLogger(classs.getName()).log(Level.WARNING,
                        "Cannot firgue out base path for class with way (2): ", ex);
            }
        }

        // fix to run inside eclipse
        if (basePath.endsWith(File.separator + "lib") || basePath.endsWith(File.separator + "bin")
                || basePath.endsWith("bin" + File.separator) || basePath.endsWith("lib" + File.separator)) {
            basePath = basePath.substring(0, basePath.length() - 4);
        }
        // fix to run inside netbeans
        if (basePath.endsWith(File.separator + "build" + File.separator + "classes")) {
            basePath = basePath.substring(0, basePath.length() - 14);
        }
        // end fix
        if (!basePath.endsWith(File.separator)) {
            basePath = basePath + File.separator;
        }
        return basePath;
    }
 0
Author: GOXR3PLUS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-19 13:12:36

Ten kod zadziałał dla mnie:

private static String getJarPath() throws IOException, URISyntaxException {
    File f = new File(LicensingApp.class.getProtectionDomain().().getLocation().toURI());
    String jarPath = f.getCanonicalPath().toString();
    String jarDir = jarPath.substring( 0, jarPath.lastIndexOf( File.separator ));
    return jarDir;
  }
 0
Author: John Lockwood,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-08 11:58:34

Ignoruj odpowiedź backup lad, może czasami wyglądać ok, ale ma kilka problemów:

Tutaj powinno być +1 a nie -1:

name = name.substring(name.lastIndexOf(':')-1, name.lastIndexOf('/')+1).replace('%', ' ');

Bardzo niebezpieczne, ponieważ nie jest od razu widoczne, jeśli ścieżka nie ma białych spacji, ale zastąpienie tylko " % " pozostawi Ci kilka 20 w każdej białej spacji:

name = name.substring(name.lastIndexOf(':')-1, name.lastIndexOf('/')+1).replace('%', ' ');

Są lepsze sposoby niż ta pętla dla białych przestrzeni.

Spowoduje to również problemy w czasie debugowania.

 -1
Author: rciafardone,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-28 01:51:21

Piszę w Javie 7 i testuję w Windows 7 z Oracle runtime, a Ubuntu z open source runtime. To działa idealnie dla tych systemów:

Ścieżka do katalogu nadrzędnego dowolnego uruchomionego pliku jar (zakładając, że Klasa wywołująca ten kod jest bezpośrednim potomkiem samego archiwum Jar):

try {
    fooDir = new File(this.getClass().getClassLoader().getResource("").toURI());
} catch (URISyntaxException e) {
    //may be sloppy, but don't really need anything here
}
fooDirPath = fooDir.toString(); // converts abstract (absolute) path to a String
/ Align = "left" / jar byłby:
fooPath = fooDirPath + File.separator + "foo.jar";
To nie było testowane na żadnym komputerze Mac lub starszym systemie Windows.]}
 -1
Author: sudoBen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-03 23:54:53

The getProtectionDomain approach may not work sometimes ever when you have to find the jar for some of the core java classes( np. in my case StringBuilder class within IBM JDK), but following working bezproblemowo:

public static void main(String[] args) {
    System.out.println(findSource(MyClass.class));
    // OR
    System.out.println(findSource(String.class));
}

public static String findSource(Class<?> clazz) {
    String resourceToSearch = '/' + clazz.getName().replace(".", "/") + ".class";
    java.net.URL location = clazz.getResource(resourceToSearch);
    String sourcePath = location.getPath();
    // Optional, Remove junk
    return sourcePath.replace("file:", "").replace("!" + resourceToSearch, "");
}
 -1
Author: Vasu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-14 18:10:30

Mam inny sposób, aby uzyskać lokalizację łańcucha klasy.

URL path = Thread.currentThread().getContextClassLoader().getResource("");
Path p = Paths.get(path.toURI());
String location = p.toString();

Łańcuch wyjściowy będzie miał postać

C:\Users\Administrator\new Workspace\...

Spacje i inne znaki są obsługiwane, a w formie bez file:/. Więc będzie łatwiejszy w użyciu.

 -1
Author: NoSegfault,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-21 18:41:50

Lub możesz przekazać aktualny wątek w ten sposób:

String myPath = Thread.currentThread().getContextClassLoader().getResource("filename").getPath();
 -1
Author: Assem BARDI,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-23 12:38:40

Ten jeden liner działa dla folderów zawierających spacje lub znaki specjalne(jak ç lub õ). Pierwotne pytanie pyta o ścieżkę bezwzględną (roboczy katalog), bez samego pliku JAR. Testowane tutaj z Java7 na Windows7:

String workingDir = System.getProperty("user.dir");

Odniesienie: http://www.mkyong.com/java/how-to-get-the-current-working-directory-in-java/

 -2
Author: Rodrigo N. Hernandez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-16 20:37:37