web-dev-qa-db-ja.com

JARファイルの場所を取得する

Runnable JARファイルが実行される場所を取得しようとしています。やってみた

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

しかし、それは戻ります:

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

jARファイルは次の場所にあります

C:\Users\Kevin\Desktop

私もやってみました

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

しかし、それは戻ります:

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

基本的に、ClassPathではなく、ファイル名なしのJARファイルのパスが必要です。

これを行う方法はありますか?

13
Snakybo

更新

特定のテストケースでは機能しないため、回答を更新します。

これを行う正しい方法は、ClassLoaderを使用することです。

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

さまざまなクラスパスでテストされ、出力は正しかった。


古い答え

これはうまくいくはずです

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

それは私のために働き、私のプログラムは次の場所にあります:

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

そして戻る

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

これで、jarディレクトリの計算の私のバージョン

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

最終的に実用的な解決策を見つける前に、私は多くのことをいじくり回さなければなりませんでした。
jarLocationには、_file:\_や_jar:file\_などの接頭辞が付いている可能性があります。これらは、String#substring()を使用して削除できます。

_URL jarLocationUrl = MyClass.class.getProtectionDomain().getCodeSource().getLocation();
String jarLocation = new File(jarLocationUrl.toString()).getParent();
_
2
Jelle

あなたが知っていれば

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

戻り値

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

そして、Jar名がserver.jarであるか、どの.jarファイルでも、C:\ Users\Kevin\Desktopを取得することが目的であることがわかります。直接的な方法は、文字列操作を行うことです。

取得した出力で、File.separatorに基づいて文字列をトークン化し、.jarを含むトークンを取得するまでパスを構築します(間に文字列をFile.separatorで連結して)

0