如何正确引用资源文件以进行JAR和调试?

时间:2011-05-31 19:40:58

标签: java eclipse jar

在使用Maven项目和Jar文件时,我有一个令人讨厌的问题引用资源...

我将所有资源都放在专用文件夹/ src / main / resources中,这是Eclipse中构建路径的一部分。使用

引用文件
getClass().getResource("/filename.txt")

这在Eclipse中运行良好但在Jar文件中失败 - 资源位于jar根目录正下方的文件夹中......

有人知道在JAR和Eclipse中的(!)中引用文件的“最佳实践”吗?

修改: 问题是虽然资源实际上位于顶层的“资源”文件夹中的JAR中,但上述方法无法找到文件......

7 个答案:

答案 0 :(得分:18)

Maven资源文件夹的内容被复制到目标/类,并从那里复制到生成的Jar文件的根目录。这是预期的行为。

我不明白的是您的方案中存在的问题。通过getClass().getResource("/filename.txt")引用资源从类路径的根开始,无论该(或其元素)是target/classes还是JAR的根。我看到的唯一可能的错误是您使用了错误的ClassLoader

确保使用该资源的类与资源位于同一工件(JAR)中并执行ThatClass.class.getResource("/path/with/slash")ThatClass.class.getClassLoader().getResource("path/without/slash")

但除此之外:如果它不起作用,你可能在构建过程中的某个地方做错了什么。你能验证资源是否在JAR中?

答案 1 :(得分:18)

我有类似的问题。 经过一整天的尝试每一个组合和调试后,我尝试了getClass()。getResourceAsStream(“resources / filename.txt”)并最终使其工作。 没有其他任何帮助。

答案 2 :(得分:17)

打包JAR后,您的资源文件不再是文件,而是流,因此getResource无效!

使用getResourceAsStream

获取"文件"内容,请使用https://commons.apache.org/proper/commons-io/javadocs/api-release/org/apache/commons/io/IOUtils.html

static public String getFile(String fileName)
{
        //Get file from resources folder
        ClassLoader classLoader = (new A_CLASS()).getClass().getClassLoader();

        InputStream stream = classLoader.getResourceAsStream(fileName);

        try
        {
            if (stream == null)
            {
                throw new Exception("Cannot find file " + fileName);
            }

            return IOUtils.toString(stream);
        }
        catch (Exception e) {
            e.printStackTrace();

            System.exit(1);
        }

        return null;
}

答案 3 :(得分:0)

也许这种方法可以在某些情况下有所帮助。

public static File getResourceFile(String relativePath)
{
    File file = null;
    URL location = <Class>.class.getProtectionDomain().getCodeSource().getLocation();
    String codeLoaction = location.toString();
    try{
        if (codeLocation.endsWith(".jar"){
            //Call from jar
            Path path = Paths.get(location.toURI()).resolve("../classes/" + relativePath).normalize();
            file = path.toFile();
        }else{
            //Call from IDE
            file = new File(<Class>.class.getClassLoader().getResource(relativePath).getPath());
        }
    }catch(URISyntaxException ex){
        ex.printStackTrace();
    }
    return file;
}

答案 4 :(得分:-1)

如果在jar文件中添加资源目录(因此它位于jar中的/ resources文件夹下,如果/ src / main位于eclipse中的构建路径中,那么您应该能够将文件引用为:

getClass().getResource("/resources/filename.txt");  

哪个应该适用于两种环境。

答案 5 :(得分:-1)

问题是在IDE中getClass()。getResource(&#34; Path&#34;);访问文件时,字符串不是CASE SENSITIVE,而是从jar运行时。检查与文件相比的目录上的大小写。它确实有效。此外,如果你尝试新的文件(getClass()。getResource(&#34; Path&#34;);该文件在IDE之外是不可读的。

答案 6 :(得分:-3)

只需将文件复制到临时目录即可。

String tempDir = System.getProperty("java.io.tmpdir");
File file = new File(tempDir.getAbsolutePath(), "filename.txt");
if (!file.exists()) {
     InputStream is = (getClass().getResourceAsStream("/filename.txt"));
     Files.copy(is, file.getAbsoluteFile().toPath());
}