简体   繁体   English

如何在运行时获取jar路径

[英]How to get jar path in runtime

I want java to look for .properties file in same folder with jar which is running. 我希望Java在与正在运行的jar相同的文件夹中查找.properties文件。 How can I do it and how can I determine if app is running in IDE or as explicit jar file 我该如何做以及如何确定应用程序是在IDE中运行还是作为显式jar文件运行

您可以通过以下方式访问此文件(如果它在类路径中):

Paths.get(this.getClass().getResource("file.properties").toURI());

Firstly I have to say that this is inherently a bad practice, though life often is not perfect and sometimes we have to roll with the bad design punches. 首先,我不得不说,这本质上是一种不好的做法,尽管生活往往并不完美,有时我们不得不忍受糟糕的设计冲击。

This is the class I mustered up for a pet project of mine that required such functionality: 这是我为我的一个宠物项目收集的类,该项目需要以下功能:

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

}

I guess a little explaining is in order... 我想有一点解释是为了...

Overall this will try to resolve a filepath for a properties file located in an arbitrary project. 总体而言,这将尝试解析位于任意项目中的属性文件的文件路径。 This means that the ArbitraryPath class does not need to be located in the same project as the properties file, this comes in handy when you want to separate for example the JUnit tests in a separate project. 这意味着ArbitraryPath类不需要与属性文件位于同一项目中,这在您要分离(例如,在单独的项目中进行JUnit测试)时非常方便。 It will identify the project based on the class you give it, the class should be in the same project as the properties file you are trying to find. 它将根据您提供的类来标识项目,该类应与您要查找的属性文件位于同一项目中。

So first of all it gets the path of the class you gave it in this line: 因此,首先它获得您在这一行中给它的类的路径:

String fullPath = requestingClass.getResource("").toURI().toString();

Then it checks whether or not this class is within a JAR file or if it is executed from the IDE. 然后,它检查此类是否在JAR文件中,或者是否从IDE执行。 This is done by checking whether the path contains "/bin/" which would normally mean that it is executed from an IDE or ".jar!" 通过检查路径是否包含“ / bin /”来完成此操作,这通常意味着它是从IDE或“ .jar!”执行的。 which would normally mean that it is executed from a JAR. 这通常意味着它是从JAR执行的。 You can modify the method if you have a different project structure. 如果您具有不同的项目结构,则可以修改该方法。

If it is determined that it is NOT run from JAR then we trim the path down to the project folder, going backwards down the path until we reach the BIN folder. 如果确定它不是从JAR运行,则我们将路径修剪到项目文件夹,然后向后向下移动路径,直到到达BIN文件夹。 Again, change this if your project structure deviates from the standard. 同样,如果您的项目结构偏离标准,请更改此设置。

(If we determine that it IS run from a JAR file then we don't trim anything since we have already got the path to the base folder.) (如果我们确定它从JAR文件运行的,那么由于已经获得了基本文件夹的路径,因此我们不会修剪任何内容。)

After that, we have retrieved a path to the project folder so we add the name of the folder (if there is one) where the properties file is located, and add the filename and extension of the properties file which we want to locate. 之后,我们检索了项目文件夹的路径,因此我们添加了属性文件所在的文件夹的名称(如果有的话),并添加了我们要查找的属性文件的文件名和扩展名。

We then return this path. 然后,我们返回此路径。 We can then use this path in an InputStream like such: 然后,我们可以在InputStream中使用此路径,如下所示:

FileInputStream in = new FileInputStream(ArbitraryPath.resolveResourceFilePath("myPropertiesFile", "configFolder", UserConfiguration.class));

Which will retrieve the myPropertiesFile.properties in the myConfiguration folder in the project folder where UserConfiguration.class is located. 它将在UserConfiguration.class所在项目文件夹的myConfiguration文件夹中检索myPropertiesFile.properties。

Please note that this class assumes you have a standard project configuration. 请注意,该类假定您具有标准项目配置。 Feel free to adapt it to your needs etc. 随时适应您的需求等。

Also this is a really hackish and crude way to do this. 同样,这是一种非常骇人听闻的原始方式。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM