it-swarm.com.de

Speicherort der JAR-Datei abrufen

Ich versuche, den Ort zu ermitteln, von dem aus eine ausführbare JAR-Datei ausgeführt wird. Ich habe es versucht

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

Aber das kehrt zurück:

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

während sich die JAR-Datei unter befindet

C:\Users\Kevin\Desktop

Ich habe es auch versucht

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

Aber das kehrt zurück:

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

Grundsätzlich möchte ich den Pfad der JAR-Datei ohne den Dateinamen und nicht den ClassPath.

Wie kann ich das machen?

13
Snakybo

Update

Da es in bestimmten Testfällen nicht funktioniert, werde ich die Antwort aktualisieren.

Der richtige Weg, dies zu tun, sollte mit ClassLoader sein:

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

Bei verschiedenen Klassenpfaden getestet, war die Ausgabe korrekt.


Alte Antwort

Das sollte funktionieren

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

Es funktioniert für mich, mein Programm ist in:

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

Und es kehrt zurück

C:\Users\User01\Documents\app1\dist
24
BackSlash

Hiermit meine Version der Berechnung des Jar-Verzeichnisses

/**
 * 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());
    }
}
17
Zweibieren

Ich musste viel herumspielen, bevor ich endlich eine funktionierende Lösung fand. 
Es ist möglich, dass jarLocation ein Präfix wie file:\ oder jar:file\ enthält, das mit String#substring() entfernt werden kann.

URL jarLocationUrl = MyClass.class.getProtectionDomain().getCodeSource().getLocation();
String jarLocation = new File(jarLocationUrl.toString()).getParent();
0
Jelle