'ClassLoader#getResourceAsStream() behaving differently in IDE and jar file
I have written following piece of code to get the list of names of files in metadata folder.
public class Demo {
public static void main(String[] args) throws IOException {
InputStream is=Demo.class.getClassLoader().getResourceAsStream("metadata");
System.out.println(is.available());
InputStreamReader isr=new InputStreamReader(is,StandardCharsets.UTF_8.name());
BufferedReader br = new BufferedReader(isr);
List<String> list=new ArrayList<>();
String line;
while((line = br.readLine()) != null) {
list.add(line);
}
System.out.println(list);
} }
Here is the project structure in Intellij IDE
This program runs as expected in IDE and prints following output:
22
[test1.json, test2.json]
However, when I build an executable jar of this program:
and run it using java -jar, the output is:
0
[]
Why does jar file behave differently?
Solution 1:[1]
Real filesystems traditionally have (or simulate) directories that can be enumerated although the OS API and thus the implementation of File(with isDirectory true).list() varies by platform, and FileURLConnection (which is used for a resource in the filesystem) returns that list as the 'contents' of a directory.
JAR files are really ZIP files, and ZIP files were designed to store files not directories as such, although the files can have slash-separated names to organize them into directories. (Always slash, even though when it was created MSDOS and Windows already used backslash in the API.) Java jar creates a dummy 'file' entry for each directory, to contain the modtime and (I think) permissions to be used when extracting/restoring, but this entry contains no data, and that's what JarURLConnection reads for a resource 'directory' in a JAR.
You can list entries under a given directory pathname in a ZIP, including a JAR, using the (j7+) NIO ZipFileSystemProvider; see my answer at Reading .cer files from jar file failing . (And for real files such as unpacked jars you can of course use the NIO default=OS filesystem the same way; that's equivalent to the 'legacy' java.io.File class.)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | dave_thompson_085 |



