Java 如何在运行时获取jar路径
我希望java在运行jar的同一文件夹中查找.properties文件。我如何做,如何确定应用程序是在IDE中运行还是作为显式jar文件运行您可以通过以下方式访问此文件(如果它在类路径中):Java 如何在运行时获取jar路径,java,properties,jar,Java,Properties,Jar,我希望java在运行jar的同一文件夹中查找.properties文件。我如何做,如何确定应用程序是在IDE中运行还是作为显式jar文件运行您可以通过以下方式访问此文件(如果它在类路径中): 首先,我不得不说,这本来就是一种糟糕的做法,尽管生活往往并不完美,有时我们不得不面对糟糕的设计 这是我为一个需要此类功能的pet项目召集的类: public class ArbitraryPath { private static Logger logger = LogManager.getLog
首先,我不得不说,这本来就是一种糟糕的做法,尽管生活往往并不完美,有时我们不得不面对糟糕的设计 这是我为一个需要此类功能的pet项目召集的类:
public class ArbitraryPath {
private static Logger logger = LogManager.getLogger("utility");
private static boolean isRunFromJar = false;
public static String resolveResourceFilePath(String fileName, String folderName, Class<?> requestingClass) throws URISyntaxException{
// ARGUMENT NULL CHECK SAFETY HERE
String fullPath = requestingClass.getResource("").toURI().toString();
isRunFromJar = isRunFromJar(fullPath);
String result = "";
if(!isRunFromJar){
result = trimPathDownToProject(requestingClass.getResource("").toURI());
}
result = result+folderName+"/"+fileName+".properties";
return result;
}
private static String trimPathDownToProject(URI previousPath){
String result = null;
while(!isClassFolderReached(previousPath)){
previousPath = previousPath.resolve("..");
}
previousPath = previousPath.resolve("..");
result = previousPath.getPath();
return result;
}
private static boolean isClassFolderReached(URI currentPath){
String checkableString = currentPath.toString();
checkableString = checkableString.substring(0,checkableString.length()-1);
checkableString = checkableString.substring(checkableString.lastIndexOf("/")+1,checkableString.length());
if(checkableString.equalsIgnoreCase("bin")){
return true;
} else {
return false;
}
}
private static boolean isRunFromJar(String fullPath) throws URISyntaxException{
String solidClassFolder = "/bin/";
String solidJarContainer = ".jar!";
if(!fullPath.contains(solidClassFolder)){
if(fullPath.contains(solidJarContainer)){
return true;
} else {
logger.error("Requesting class is not located within a supported project structure!");
throw new IllegalArgumentException("Requesting class must be within a bin folder!");
}
} else {
return false;
}
}
}
然后检查该类是否在JAR文件中,或者是否从IDE执行。这是通过检查路径是否包含“/bin/”来完成的,这通常意味着它是从IDE执行的,.jar!”通常意味着它是从jar执行的。如果具有不同的项目结构,则可以修改该方法
如果确定它是而不是从JAR运行,那么我们将向下修剪路径到项目文件夹,沿着路径向后走,直到到达BIN文件夹。同样,如果您的项目结构偏离标准,请更改此项
(如果我们确定它是从JAR文件运行的,那么我们不会修剪任何东西,因为我们已经获得了基本文件夹的路径。)
之后,我们检索到了项目文件夹的路径,因此我们添加了属性文件所在的文件夹的名称(如果有),并添加了要定位的属性文件的文件名和扩展名
然后我们返回这条路径。然后,我们可以在InputStream中使用此路径,如下所示:
FileInputStream in = new FileInputStream(ArbitraryPath.resolveResourceFilePath("myPropertiesFile", "configFolder", UserConfiguration.class));
它将在UserConfiguration.class所在的项目文件夹中的myConfiguration文件夹中检索myPropertiesFile.properties
请注意,此类假定您具有标准项目配置。
随时根据您的需要进行调整
而且,这是一种非常粗俗的方法。不是很好的方法。您应该1)将属性放在jar文件中,或者2)将属性放在相对于当前工作目录的某个位置(可能在启动jar之前更改cwd),或者3)将属性放在相同的已知位置(按环境硬编码或可配置)(think/etc/myapp/config.props),但如果必须这样做,那么:,这有点黑客味,给我几分钟时间,我会在我的文件中找到它,然后发布一个答案。不过,可能不会在类路径上。
String absolutePath = null;
try {
absolutePath = (new File(Utils.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath())).getCanonicalPath();
absolutePath = absolutePath.substring(0, absolutePath.lastIndexOf(File.separator))+File.separator;
} catch (URISyntaxException ex) {
Logger.getLogger(Utils.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Utils.class.getName()).log(Level.SEVERE, null, ex);
}
FileInputStream in = new FileInputStream(ArbitraryPath.resolveResourceFilePath("myPropertiesFile", "configFolder", UserConfiguration.class));
String absolutePath = null;
try {
absolutePath = (new File(Utils.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath())).getCanonicalPath();
absolutePath = absolutePath.substring(0, absolutePath.lastIndexOf(File.separator))+File.separator;
} catch (URISyntaxException ex) {
Logger.getLogger(Utils.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Utils.class.getName()).log(Level.SEVERE, null, ex);
}