2013-03-12 17 views
12

Próbuję uzyskać lokalizację, z której uruchamiany jest uruchamiany plik JAR. Próbowałem robićUzyskaj lokalizację pliku JAR

try { 
    String path = new java.io.File(".").getCanonicalPath(); 
} catch (IOException e) { 
    e.printStackTrace(); 
} 

Ale powraca:

C:\Users\Kevin\Desktop/server/Server 

gdy plik JAR znajduje się

C:\Users\Kevin\Desktop 

Próbowałem też robi

return new file(Server.class.getProtectionDomain().getCodeSource().getLocation().getPath()); 

ale powroty :

C:\Users\Kevin\Desktop\server.jar/server/Server 

Tak zasadniczo chcę ścieżki pliku JAR bez nazwy pliku, a nie ClassPath.

Jakikolwiek sposób to zrobić?

+1

To może być pomocne, niewidoczne dyskusja. http://stackoverflow.com/questions/320542/how-to-get-the-path--running-jar-file // Henrik – Hiny

+0

Specyfikacja jest niekompletna. Co należy zrobić, jeśli nie * nie * działasz z pliku JAR? Co jeśli JAR mieszka w jakiejś sieci? – Ingo

+0

Chodzi o to, że próbuję utworzyć katalog zawierający pliki, które musi znajdować się na moim pulpicie lub w dowolnym miejscu, w którym uruchamiam plik JAR. Jeśli uruchomię go w trybie debugowania w środowisku Eclipse, tworzy pliki w folderze bin/server. – Snakybo

Odpowiedz

16

Aktualizacja

Ponieważ nie działa w niektórych przypadkach testowych, zaktualizuję odpowiedź.

Poprawny sposób, aby to zrobić należy z ClassLoader:

File jarDir = new File(ClassLoader.getSystemClassLoader().getResource(".").getPath()); 
System.out.println(jarDir.getAbsolutePath()); 

Testowane na różnych ścieżek klas, wyjście było prawidłowe.


Old odpowiedź

To powinno działać

File f = new File(System.getProperty("java.class.path")); 
File dir = f.getAbsoluteFile().getParentFile(); 
String path = dir.toString(); 

to działa na mnie, mój program jest w:

C:\Users\User01\Documents\app1\dist\JavaApplication1.jar 

I zwraca

C:\Users\User01\Documents\app1\dist 
+5

Działa to tylko tak długo, jak ścieżka klas zawiera tylko jeden wpis. – Ingo

+0

@BackSlash czy kiedykolwiek próbowałeś powyższego kodu na systemie Linux/Unix czy to działa idealnie? – dbw

+0

@Ingo "classpath zawiera tylko jeden wpis" co to właściwie oznacza ... ?? – dbw

-1

Jeśli znasz

file(Server.class.getProtectionDomain().getCodeSource().getLocation().getPath()); 

powraca

C:\Users\Kevin\Desktop\server.jar/server/Server 

i wiesz imię i nazwisko Jar jest server.jar lub za sprawą dowolnego pliku JAR, twoim zamiarem jest, aby C: \ Users \ Kevin \ Desktop, prosta droga to manipulowanie strunami.

Z pobranego wyjściu tokenize ciąg w oparciu o File.separator i zbudować ścieżkę (przez złączenie sznurki z File.separator pomiędzy), aż pojawi się znak, który zawiera .jar

+0

Tak, ale co jeśli użytkownicy zdecydują się zmienić nazwę JAR? – Snakybo

+0

Nie powinieneś wyszukiwać z zaszyfrowanymi nazwami plików jar, najlepiej po pobraniu tokena, powinieneś sprawdzić, czy to token.contains (.jar), to zadziała, jakkolwiek będziesz mógł, nazwa pliku JAR –

+0

Nie, nie będzie, dla przykład, jeśli zmieniono nazwę na ZIP – Ingo

15

Niniejszym moja wersja obliczania katalogu słoik

/** 
* Compute the absolute file path to the jar file. 
* The framework is based on http://stackoverflow.com/a/12733172/1614775 
* But that gets it right for only one of the four cases. 
* 
* @param aclass A class residing in the required jar. 
* 
* @return A File object for the directory in which the jar file resides. 
* During testing with NetBeans, the result is ./build/classes/, 
* which is the directory containing what will be in the jar. 
*/ 
public static File getJarDir(Class aclass) { 
    URL url; 
    String extURL;  // url.toExternalForm(); 

    // get an url 
    try { 
     url = aclass.getProtectionDomain().getCodeSource().getLocation(); 
      // url is in one of two forms 
      //  ./build/classes/ NetBeans test 
      //  jardir/JarName.jar froma jar 
    } catch (SecurityException ex) { 
     url = aclass.getResource(aclass.getSimpleName() + ".class"); 
     // url is in one of two forms, both ending "/com/physpics/tools/ui/PropNode.class" 
     //   file:/U:/Fred/java/Tools/UI/build/classes 
     //   jar:file:/U:/Fred/java/Tools/UI/dist/UI.jar! 
    } 

    // convert to external form 
    extURL = url.toExternalForm(); 

    // prune for various cases 
    if (extURL.endsWith(".jar")) // from getCodeSource 
     extURL = extURL.substring(0, extURL.lastIndexOf("/")); 
    else { // from getResource 
     String suffix = "/"+(aclass.getName()).replace(".", "/")+".class"; 
     extURL = extURL.replace(suffix, ""); 
     if (extURL.startsWith("jar:") && extURL.endsWith(".jar!")) 
      extURL = extURL.substring(4, extURL.lastIndexOf("/")); 
    } 

    // convert back to url 
    try { 
     url = new URL(extURL); 
    } catch (MalformedURLException mux) { 
     // leave url unchanged; probably does not happen 
    } 

    // convert url to File 
    try { 
     return new File(url.toURI()); 
    } catch(URISyntaxException ex) { 
     return new File(url.getPath()); 
    } 
} 
0

miałem bałagan wokół partii przed końcu znalazłem roztwór roboczy.
Możliwe jest, że jarLocation ma prefiks taki jak 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(); 
Powiązane problemy