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

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


当前回答

我已经尝试了上面的几种解决方案,但是对于在Eclipse中使用“打包外部库”导出可运行jar的情况(可能是特殊情况),没有一个产生正确的结果。出于某种原因,所有基于ProtectionDomain的解决方案在这种情况下都将导致null。

通过结合上面的一些解决方案,我成功地实现了以下工作代码:

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

其他回答

对我来说,在Linux、Mac和Windows上都适用的唯一解决方案是:

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

不太确定其他人,但在我的情况下,它不与“可运行的罐子”,我得到了它的工作通过修复代码一起从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");

令人沮丧的是,当您在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");
}

我用Java 7编写,用Oracle的运行时在Windows 7上测试,用开源运行时在Ubuntu上测试。这对于这些系统来说是完美的:

任何正在运行的jar文件的父目录的路径(假设调用这段代码的类是jar存档本身的直接子目录):

try {
    fooDir = new File(this.getClass().getClassLoader().getResource("").toURI());
} catch (URISyntaxException e) {
    //may be sloppy, but don't really need anything here
}
fooDirPath = fooDir.toString(); // converts abstract (absolute) path to a String

因此,foo.jar的路径是:

fooPath = fooDirPath + File.separator + "foo.jar";

同样,这也没有在任何Mac或旧版本的Windows上进行测试

对我来说最好的解决方案:

String path = Test.class.getProtectionDomain().getCodeSource().getLocation().getPath();
String decodedPath = URLDecoder.decode(path, "UTF-8");

这应该可以解决空格和特殊字符的问题。