Получить местоположение файла JAR
Я пытаюсь получить местоположение из Runnable JAR файла.
Я пробовал делать
try {
String path = new java.io.File(".").getCanonicalPath();
} catch (IOException e) {
e.printStackTrace();
}
Но это возвращает:
C:\Users\Kevin\Desktop/server/Server
в то время как файл JAR находится в
C:\Users\Kevin\Desktop
Я также пробовал делать
return new file(Server.class.getProtectionDomain().getCodeSource().getLocation().getPath());
Но это возвращает:
C:\Users\Kevin\Desktop\server.jar/server/Server
Так что, я хочу, чтобы путь к файлу JAR был без имени файла, а не ClassPath.
Как это сделать?
Ответы
Ответ 1
Обновление
Так как он не работает в некоторых тестовых случаях, я обновляю ответ.
Правильный способ сделать это должен быть с ClassLoader
:
File jarDir = new File(ClassLoader.getSystemClassLoader().getResource(".").getPath());
System.out.println(jarDir.getAbsolutePath());
Протестировано на разных путях классов, результат был верным.
Старый ответ
Это должно работать
File f = new File(System.getProperty("java.class.path"));
File dir = f.getAbsoluteFile().getParentFile();
String path = dir.toString();
Он работает для меня, моя программа находится в:
C:\Users\User01\Documents\app1\dist\JavaApplication1.jar
И он возвращает
C:\Users\User01\Documents\app1\dist
Ответ 2
При этом моя версия вычисления каталога jar
/**
* Compute the absolute file path to the jar file.
* The framework is based on http://stackoverflow.com/a/12733172/1614775
* But that gets it right for only one of the four cases.
*
* @param aclass A class residing in the required jar.
*
* @return A File object for the directory in which the jar file resides.
* During testing with NetBeans, the result is ./build/classes/,
* which is the directory containing what will be in the jar.
*/
public static File getJarDir(Class aclass) {
URL url;
String extURL; // url.toExternalForm();
// get an url
try {
url = aclass.getProtectionDomain().getCodeSource().getLocation();
// url is in one of two forms
// ./build/classes/ NetBeans test
// jardir/JarName.jar froma jar
} catch (SecurityException ex) {
url = aclass.getResource(aclass.getSimpleName() + ".class");
// url is in one of two forms, both ending "/com/physpics/tools/ui/PropNode.class"
// file:/U:/Fred/java/Tools/UI/build/classes
// jar:file:/U:/Fred/java/Tools/UI/dist/UI.jar!
}
// convert to external form
extURL = url.toExternalForm();
// prune for various cases
if (extURL.endsWith(".jar")) // from getCodeSource
extURL = extURL.substring(0, extURL.lastIndexOf("/"));
else { // from getResource
String suffix = "/"+(aclass.getName()).replace(".", "/")+".class";
extURL = extURL.replace(suffix, "");
if (extURL.startsWith("jar:") && extURL.endsWith(".jar!"))
extURL = extURL.substring(4, extURL.lastIndexOf("/"));
}
// convert back to url
try {
url = new URL(extURL);
} catch (MalformedURLException mux) {
// leave url unchanged; probably does not happen
}
// convert url to File
try {
return new File(url.toURI());
} catch(URISyntaxException ex) {
return new File(url.getPath());
}
}
Ответ 3
Мне пришлось много возиться до того, как я наконец нашел рабочее решение.
Возможно, что jarLocation
поставляется с префиксом типа file:\
или jar:file\
, который можно удалить с помощью String#substring()
.
URL jarLocationUrl = MyClass.class.getProtectionDomain().getCodeSource().getLocation();
String jarLocation = new File(jarLocationUrl.toString()).getParent();
Ответ 4
Если вы знаете
file(Server.class.getProtectionDomain().getCodeSource().getLocation().getPath());
возвращает
C:\Users\Kevin\Desktop\server.jar/server/Server
И вы знаете, что ваше имя Jar - server.jar или для любого файла .jar, вы намерены получить C:\Users\Kevin\Desktop, прямолинейный путь - сделать строковые манипуляции.
С извлеченным выводом, tokenize строку на основе File.separator и построить путь (путем объединения строк с File.separator между ними), пока вы не получите токен, который содержит .jar