Java 如何获取正在运行的JAR文件的路径?

Java 如何获取正在运行的JAR文件的路径?,java,path,jar,executable-jar,Java,Path,Jar,Executable Jar,我的代码在JAR文件中运行,比如说foo.JAR,我需要知道在代码中运行的foo.JAR在哪个文件夹中 因此,如果foo.jar位于C:\foo\中,则无论当前工作目录是什么,我都希望获得该路径。使用ClassLoader.getResource()查找当前类的URL 例如: package foo; public class Test { public static void main(String[] args) { ClassLoader loader =

我的代码在JAR文件中运行,比如说foo.JAR,我需要知道在代码中运行的foo.JAR在哪个文件夹中


因此,如果foo.jar位于
C:\foo\
中,则无论当前工作目录是什么,我都希望获得该路径。

使用ClassLoader.getResource()查找当前类的URL

例如:

package foo;

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

要查找目录,您需要手动拆分URL。有关jar URL的格式,请参见

return new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation()
    .toURI()).getPath();
将“MyClass”替换为类的名称

显然,如果您的类是从非文件位置加载的,那么这将产生奇怪的结果

String path = getClass().getResource("").getPath();

路径始终指向jar文件中的资源。

此方法从存档中的代码调用,返回.jar文件所在的文件夹。它应该在Windows或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);
  } 


源于代码:

实际上这里有一个更好的版本-如果文件夹名中有空格,则旧版本失败

  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);
  }
私有字符串getJarFolder(){
//获取名称和路径
字符串名称=getClass().getName().replace('.','/');
name=getClass().getResource(“/”+name+“.class”).toString();
//清除垃圾
name=name.substring(0,name.indexOf(“.jar”);
name=name.substring(name.lastIndexOf(':')-1,name.lastIndexOf('/')+1)。替换('%','');
//删除转义字符
字符串s=“”;
对于(int k=0;k我的最佳解决方案:

String path = Test.class.getProtectionDomain().getCodeSource().getLocation().getPath();
String decodedPath = URLDecoder.decode(path, "UTF-8");
这将解决空格和特殊字符的问题。

您还可以使用:

CodeSource codeSource = YourMainClass.class.getProtectionDomain().getCodeSource();
File jarFile = new File(codeSource.getLocation().toURI().getPath());
String jarDir = jarFile.getParentFile().getPath();

如果从Gnome桌面环境(而不是从任何脚本或终端)单击jar来运行jar,则上面选择的答案不起作用

相反,我认为以下解决方案适用于所有地方:

    try {
        return URLDecoder.decode(ClassLoader.getSystemClassLoader().getResource(".").getPath(), "UTF-8");
    } catch (UnsupportedEncodingException e) {
        return "";
    }

这里是对其他评论的升级,在我看来,这些评论对于网站的细节来说是不完整的

在.jar文件外使用相对的“文件夹”(在jar的同一个文件夹中) 地点):


要获取给定
类的
文件
,有两个步骤:

  • 转换为
    URL
  • URL
    转换为
    文件
  • 理解这两个步骤很重要,不要将它们混为一谈

    一旦有了
    文件
    ,您就可以调用
    getParentFile
    来获取包含该文件的文件夹(如果您需要的话)

    第1步:
    Class
    URL
    正如在其他答案中所讨论的,有两种主要方法可以找到与
    类相关的
    URL

  • URL=Bar.class.getProtectionDomain().getCodeSource().getLocation();

  • URL=Bar.class.getResource(Bar.class.getSimpleName()+“.class”);

  • 两者都有利弊


    getProtectionDomain
    方法生成类的基本位置(例如,包含的JAR文件)。但是,Java运行时的安全策略在调用
    getProtectionDomain()时可能会抛出
    SecurityException
    ,因此,如果您的应用程序需要在各种环境中运行,最好在所有环境中进行测试

    getResource
    方法生成类的完整URL资源路径,您需要从中执行额外的字符串操作。它可能是
    文件:
    路径,但也可能是
    jar:file:
    或类似于
    捆绑包的更糟糕的东西eresource://346.fwk2106232034:4/foo/Bar.class
    执行w时相反地,
    getProtectionDomain
    方法可以正确地生成一个
    文件:
    URL,甚至可以从OSGi内部生成

    请注意,当类位于JAR文件中时,
    getResource(“”
    getResource(“”
    在我的测试中都失败了;两个调用都返回null。因此我建议使用上面显示的#2调用,因为这似乎更安全

    第二步:
    URL
    文件
    无论哪种方式,一旦你有了一个
    URL
    ,下一步就是转换成
    文件
    。这是它自己的挑战;有关完整的细节,请参阅,但简而言之,只要URL格式完全正确,你就可以使用
    新文件(URL.toURI())

    最后,我强烈建议不要使用
    urldecker
    。URL的某些字符,
    /
    尤其是,它们不是有效的URL编码字符。来自Javadoc:

    假设编码字符串中的所有字符都是以下字符之一:“a”到“z”、“a”到“z”、“0”到“9”和“-”、“_“、””和“*”。允许使用字符“%”,但将其解释为特殊转义序列的开始

    此解码器处理非法字符串有两种可能的方式。它可以不处理非法字符,也可以抛出IllegalArgumentException。解码器采用的方法由实现决定

    实际上,
    URLDecoder
    通常不会像上面威胁的那样抛出
    IllegalArgumentException
    。如果您的文件路径包含编码为
    %20
    的空格,这种方法可能会起作用。但是,如果您的文件路径包含其他非字母数字字符,例如
    +
    ,您将遇到
    URLDecode>的问题r
    损坏文件路径

    工作代码 要实现这些步骤,可以使用以下方法:

    /**
     * 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);
    }
    
    /**
    *获取给定类的基位置。
    *
    *如果类直接位于文件系统上(例如。,
    *“/path/to/my/package/MyClass.class”),然后它将返回基本目录
    *(例如,“文件:/path/to”)。
    *

    * *如果类位于JAR文件中(例如。, *“/path/to/my jar.jar!/my/package/MyClass.class”),然后它将返回 *JAR的路径(例如,“file:/path/to/my JAR.JAR”)。 *

    * *@param c所需位置的类。 *@see FileUtils#urlT
    /**
     * 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);
    }
    
    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;}
    
    File currentJavaJarFile = new File(Main.class.getProtectionDomain().getCodeSource().getLocation().getPath());   
    String currentJavaJarFilePath = currentJavaJarFile.getAbsolutePath();
    String currentRootDirectoryPath = currentJavaJarFilePath.replace(currentJavaJarFile.getName(), "");
    
    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();
    }
    
    Path path = Paths.get(Test.class.getProtectionDomain().getCodeSource().getLocation().toURI());
    
    String folder = MyClassName.class.getProtectionDomain().getCodeSource().getLocation().getPath();
    
    File test = new File(folder);
    if(file.isDirectory() && file.canRead()) { //always false }
    
    String fold= new File(folder).getParentFile().getPath()
    File test = new File(fold);
    
    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, "");
    }
    
    URL path = Thread.currentThread().getContextClassLoader().getResource("");
    Path p = Paths.get(path.toURI());
    String location = p.toString();
    
    C:\Users\Administrator\new Workspace\...
    
    java -jar my-jar.jar .
    
    System.getProperty("java.class.path")
    
    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");
    }
    
    return new File(MyClass.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath()).getParentFile();
    
                   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");
    
    URL jarLocationUrl = MyClass.class.getProtectionDomain().getCodeSource().getLocation();
    String jarLocation = new File(jarLocationUrl.toString()).getParent();
    
    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;
      }
    
    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);
    
    String path = new File("").getAbsolutePath();
    
    private static boolean isRunningOverJar() {
        try {
            String pathJar = Application.class.getResource(Application.class.getSimpleName() + ".class").getFile();
    
            if (pathJar.toLowerCase().contains(".jar")) {
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            return false;
        }
    }
    
        private static String getPathJar() {
            try {
                final URI jarUriPath =
                        Application.class.getResource(Application.class.getSimpleName() + ".class").toURI();
                String jarStringPath = jarUriPath.toString().replace("jar:", "");
                String jarCleanPath  = Paths.get(new URI(jarStringPath)).toString();
    
                if (jarCleanPath.toLowerCase().contains(".jar")) {
                    return jarCleanPath.substring(0, jarCleanPath.lastIndexOf(".jar") + 4);
                } else {
                    return null;
                }
            } catch (Exception e) {
                log.error("Error getting JAR path.", e);
                return null;
            }
        }
    
    @SpringBootApplication
    public class Application implements CommandLineRunner {
        public static void main(String[] args) throws IOException {
            Console console = System.console();
    
            if (console == null && !GraphicsEnvironment.isHeadless() && isRunningOverJar()) {
                Runtime.getRuntime().exec(new String[]{"cmd", "/c", "start", "cmd", "/k",
                        "java -jar \"" + getPathJar() + "\""});
            } else {
                SpringApplication.run(Application.class, args);
            }
        }
    
        @Override
        public void run(String... args) {
            /*
            Additional code here...
            */
        }
    
        private static boolean isRunningOverJar() {
            try {
                String pathJar = Application.class.getResource(Application.class.getSimpleName() + ".class").getFile();
    
                if (pathJar.toLowerCase().contains(".jar")) {
                    return true;
                } else {
                    return false;
                }
            } catch (Exception e) {
                return false;
            }
        }
    
        private static String getPathJar() {
            try {
                final URI jarUriPath =
                        Application.class.getResource(Application.class.getSimpleName() + ".class").toURI();
                String jarStringPath = jarUriPath.toString().replace("jar:", "");
                String jarCleanPath  = Paths.get(new URI(jarStringPath)).toString();
    
                if (jarCleanPath.toLowerCase().contains(".jar")) {
                    return jarCleanPath.substring(0, jarCleanPath.lastIndexOf(".jar") + 4);
                } else {
                    return null;
                }
            } catch (Exception e) {
                return null;
            }
        }
    }
    
    new File(".").getCanonicalPath()
    
    String localPath=new File(getClass().getProtectionDomain().getCodeSource().getLocation().toURI()).getParentFile().getPath()+"\\"; 
    
    "C:\Users\User\Desktop\Folder\"