Reading a resource file from within jar
Rather than trying to address the resource as a File just ask the ClassLoader to return an InputStream for the resource instead via getResourceAsStream:
InputStream in = getClass().getResourceAsStream("/file.txt"); BufferedReader reader = new BufferedReader(new InputStreamReader(in));
As long as the file.txt
resource is available on the classpath then this approach will work the same way regardless of whether the file.txt
resource is in a classes/
directory or inside a jar
.
The URI is not hierarchical
occurs because the URI for a resource within a jar file is going to look something like this: file:/example.jar!/file.txt
. You cannot read the entries within a jar
(a zip
file) like it was a plain old File.
This is explained well by the answers to:
To access a file in a jar you have two options:
Place the file in directory structure matching your package name (after extracting .jar file, it should be in the same directory as .class file), then access it using
getClass().getResourceAsStream("file.txt")
Place the file at the root (after extracting .jar file, it should be in the root), then access it using
Thread.currentThread().getContextClassLoader().getResourceAsStream("file.txt")
The first option may not work when jar is used as a plugin.
I had this problem before and I made fallback way for loading. Basically first way work within .jar file and second way works within eclipse or other IDE.
public class MyClass { public static InputStream accessFile() { String resource = "my-file-located-in-resources.txt"; // this is the path within the jar file InputStream input = MyClass.class.getResourceAsStream("/resources/" + resource); if (input == null) { // this is how we load file within editor (eg eclipse) input = MyClass.class.getClassLoader().getResourceAsStream(resource); } return input; }}