我的代码在一个JAR文件中运行,比如foo.jar,我需要知道,在代码中,运行的foo.jar在哪个文件夹中。
所以,如果FOO .jar在C:\FOO\中,无论我当前的工作目录是什么,我都想获得这个路径。
我的代码在一个JAR文件中运行,比如foo.jar,我需要知道,在代码中,运行的foo.jar在哪个文件夹中。
所以,如果FOO .jar在C:\FOO\中,无论我当前的工作目录是什么,我都想获得这个路径。
当前回答
这段代码用于识别程序是否在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;
}
}
}
其他回答
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;}
在Windows上运行良好
我用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上进行测试
令人沮丧的是,当您在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");
}
使用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的格式,请参阅JarClassLoader教程。
对我来说,在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();
}