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

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


当前回答

试试这个:

String path = new File("").getAbsolutePath();

其他回答

上述方法在我的Spring环境中并不适用,因为Spring将实际的类隐藏到一个名为BOOT-INF的包中,因此不是运行文件的实际位置。我发现了另一种方法来检索运行文件通过权限对象已授予运行文件:


public static Path getEnclosingDirectory() {
    return Paths.get(FileUtils.class.getProtectionDomain().getPermissions()
            .elements().nextElement().getName()).getParent();
}

对我来说,在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();
}

我已经尝试了上面的几种解决方案,但是对于在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);

这里是其他评论的升级版,在我看来,这些评论的细节并不完整

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

String path = 
  YourMainClassName.class.getProtectionDomain().
  getCodeSource().getLocation().getPath();

path = 
  URLDecoder.decode(
    path, 
    "UTF-8");

BufferedImage img = 
  ImageIO.read(
    new File((
        new File(path).getParentFile().getPath()) +  
        File.separator + 
        "folder" + 
        File.separator + 
        "yourfile.jpg"));

最简单的解决方案是在运行jar时将路径作为参数传递。

你可以用一个shell脚本(Windows中的.bat,其他任何地方的.sh)自动化这个:

java -jar my-jar.jar .

我用过。传递当前工作目录。

更新

您可能希望将jar文件放在子目录中,这样用户就不会意外地单击它。您的代码还应该检查以确保提供了命令行参数,如果缺少参数,则提供良好的错误消息。