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

所以,如果FOO .jar在C:\FOO\中,无论我当前的工作目录是什么,我都想获得这个路径。


当前回答

令人沮丧的是,当您在Eclipse中进行开发时,MyClass.class.getProtectionDomain(). getcodesource (). getlocation()返回/bin目录,这很好,但当您将其编译到jar时,该路径包括/myjarname.jar部分,这为您提供了非法的文件名。

为了让代码既能在ide中工作,又能编译到jar中,我使用了下面这段代码:

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

其他回答

我有另一种方法来获取类的String位置。

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

输出字符串的形式为

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

空格和其他字符被处理,并且在没有file:/的形式。这样会更容易使用。

我很惊讶地发现,最近没有人建议使用Path。以下是引用:“Path类包括各种方法,可用于获取路径信息、访问路径元素、将路径转换为其他形式或提取路径的部分”

因此,一个好的替代方法是获取Path对象为:

Path path = Paths.get(Test.class.getProtectionDomain().getCodeSource().getLocation().toURI());

不太确定其他人,但在我的情况下,它不与“可运行的罐子”,我得到了它的工作通过修复代码一起从phchen2答案和另一个从这个链接:如何获得一个运行的jar文件的路径? 代码:

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

这段代码用于识别程序是否在JAR文件或IDE中执行:

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

如果我需要获得JAR文件的Windows完整路径,我使用这个方法:

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

我的完整代码使用CommandLineRunner实现与Spring Boot应用程序一起工作,以确保应用程序总是在控制台视图中执行(在JAR文件名中错误地双击),我使用下面的代码:

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

其他答案似乎指向的代码源是Jar文件的位置,而不是一个目录。

Use

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