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