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

时间:2021-01-23 17:14:43

I have a nasty problem referencing resources when using a Maven project and Jar files...

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

I have all my resources in a dedicated folder /src/main/resources which is part of the build path in Eclipse. Files are referenced using

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

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

This works fine in Eclipse but fails in the Jar file - there the resources are located in a folder directly below the jar's root...

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

Does anyone know a 'best practice' to reference a file both in the JAR and (!) in Eclipse?

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

Edit: The problem is that while the resources actually are located in the JAR in a folder "resources" at the top level, the above method fails to find the file...

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

6 个解决方案

#1


15  

The contents of Maven resource folders are copied to target/classes and from there to the root of the resulting Jar file. That is the expected behaviour.

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

What I don't understand is what the problem is in your scenario. Referencing a Resource through getClass().getResource("/filename.txt") starts at the root of the classpath, whether that (or an element of it) is target/classes or the JAR's root. The only possible error I see is that you are using the wrong ClassLoader.

我不明白的是你的场景中存在的问题。通过getClass()引用资源.getResource(“/ filename.txt”)从类路径的根开始,无论是(或其元素)是目标/类还是JAR的根。我看到的唯一可能的错误是你使用了错误的ClassLoader。

Make sure that the class that uses the resource is in the same artifact (JAR) as the resource and do ThatClass.class.getResource("/path/with/slash") or ThatClass.class.getClassLoader().getResource("path/without/slash").

确保使用该资源的类与资源位于同一工件(JAR)中,并执行ThatClass.class.getResource(“/ path / with / slash”)或ThatClass.class.getClassLoader()。getResource(“path” /没有/斜线“)。

But apart from that: if it isn't working, you are probably doing something wrong somewhere in the build process. Can you verify that the resource is in the JAR?

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

#2


17  

I had a similar problem. After a full day of trying every combination and debugging I tried getClass().getResourceAsStream("resources/filename.txt") and got it to work finally. Nothing else helped.

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

#3


13  

Once you pack the JAR, your resource files are not files any more, but stream, so getResource will not work!

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

Use getResourceAsStream.

使用getResourceAsStream。

To get the "file" content, use https://commons.apache.org/proper/commons-io/javadocs/api-release/org/apache/commons/io/IOUtils.html:

要获取“文件”内容,请使用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;
}

#4


0  

The problem is that within the IDE the getClass().getResource("Path"); String is not CASE SENSITIVE when accessing a file but when running from a jar it is. Check your Capitalisation on directory compared to file. It does work. Also if you try new File(getClass().getResource("Path"); the file won't be readable outside IDE.

问题是在IDE中getClass()。getResource(“Path”);访问文件时,字符串不是CASE SENSITIVE,而是从jar运行时。检查目录上的Capitalization与文件比较。它确实有效。此外,如果您尝试新的File(getClass()。getResource(“Path”);该文件将无法在IDE外部读取。

#5


-1  

If you add the resources directory in the jar file (so it is under the /resources folder in the jar, and if /src/main is in your build path in eclipse, then you should be able to reference your file as:

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

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

Which should work in both environments.

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

#6


-3  

Just copy the file to a temporary directory.

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

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

#1


15  

The contents of Maven resource folders are copied to target/classes and from there to the root of the resulting Jar file. That is the expected behaviour.

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

What I don't understand is what the problem is in your scenario. Referencing a Resource through getClass().getResource("/filename.txt") starts at the root of the classpath, whether that (or an element of it) is target/classes or the JAR's root. The only possible error I see is that you are using the wrong ClassLoader.

我不明白的是你的场景中存在的问题。通过getClass()引用资源.getResource(“/ filename.txt”)从类路径的根开始,无论是(或其元素)是目标/类还是JAR的根。我看到的唯一可能的错误是你使用了错误的ClassLoader。

Make sure that the class that uses the resource is in the same artifact (JAR) as the resource and do ThatClass.class.getResource("/path/with/slash") or ThatClass.class.getClassLoader().getResource("path/without/slash").

确保使用该资源的类与资源位于同一工件(JAR)中,并执行ThatClass.class.getResource(“/ path / with / slash”)或ThatClass.class.getClassLoader()。getResource(“path” /没有/斜线“)。

But apart from that: if it isn't working, you are probably doing something wrong somewhere in the build process. Can you verify that the resource is in the JAR?

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

#2


17  

I had a similar problem. After a full day of trying every combination and debugging I tried getClass().getResourceAsStream("resources/filename.txt") and got it to work finally. Nothing else helped.

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

#3


13  

Once you pack the JAR, your resource files are not files any more, but stream, so getResource will not work!

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

Use getResourceAsStream.

使用getResourceAsStream。

To get the "file" content, use https://commons.apache.org/proper/commons-io/javadocs/api-release/org/apache/commons/io/IOUtils.html:

要获取“文件”内容,请使用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;
}

#4


0  

The problem is that within the IDE the getClass().getResource("Path"); String is not CASE SENSITIVE when accessing a file but when running from a jar it is. Check your Capitalisation on directory compared to file. It does work. Also if you try new File(getClass().getResource("Path"); the file won't be readable outside IDE.

问题是在IDE中getClass()。getResource(“Path”);访问文件时,字符串不是CASE SENSITIVE,而是从jar运行时。检查目录上的Capitalization与文件比较。它确实有效。此外,如果您尝试新的File(getClass()。getResource(“Path”);该文件将无法在IDE外部读取。

#5


-1  

If you add the resources directory in the jar file (so it is under the /resources folder in the jar, and if /src/main is in your build path in eclipse, then you should be able to reference your file as:

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

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

Which should work in both environments.

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

#6


-3  

Just copy the file to a temporary directory.

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

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