I have a resources folder/package in the root of my project, I "don't" want to load a certain File. If I wanted to load a certain File, I would use class.getResourceAsStream and I would be fine!! What I actually want to do is to load a "Folder" within the resources folder, loop on the Files inside that Folder and get a Stream to each file and read in the content... Assume that the File names are not determined before runtime... What should I do? Is there a way to get a list of the files inside a Folder in your jar File? Notice that the Jar file with the resources is the same jar file from which the code is being run...
-
1This would help : http://stackoverflow.com/questions/1529611/how-to-write-a-java-program-which-can-extract-a-jar-file-and-store-its-data-in-s – jmj Jun 13 '12 at 10:27
-
Also see: http://stackoverflow.com/questions/4764347/extract-and-load-dll-from-jar – jmj Jun 13 '12 at 10:29
-
5The First one is about extracting a jar file, which is kind of the last thing I want to try, like an if-worse-comes-to-worse situation!! If I want the files extracted, I would just put them in my installation folder at installation time! I want to access them from inside the jar, and my reason is, if getResourceAsStream can access a File, Java should also be able to explore folders in that jar, without the need to extract it!! But thanks... – Mostafa Zeinali Jun 14 '12 at 05:38
12 Answers
Finally, I found the solution:
final String path = "sample/folder";
final File jarFile = new File(getClass().getProtectionDomain().getCodeSource().getLocation().getPath());
if(jarFile.isFile()) { // Run with JAR file
final JarFile jar = new JarFile(jarFile);
final Enumeration<JarEntry> entries = jar.entries(); //gives ALL entries in jar
while(entries.hasMoreElements()) {
final String name = entries.nextElement().getName();
if (name.startsWith(path + "/")) { //filter according to the path
System.out.println(name);
}
}
jar.close();
} else { // Run with IDE
final URL url = Launcher.class.getResource("/" + path);
if (url != null) {
try {
final File apps = new File(url.toURI());
for (File app : apps.listFiles()) {
System.out.println(app);
}
} catch (URISyntaxException ex) {
// never happens
}
}
}
The second block just work when you run the application on IDE (not with jar file), You can remove it if you don't like that.

- 9,008
- 4
- 43
- 54
-
Updated the correct answer. Although this is not what I would like to do, especially in a code with 34000+ source files... But it seems to be the only solution. Thank you. – Mostafa Zeinali Oct 08 '15 at 11:03
-
4FYI, this doesn't work if launched from webstart because getPath returns something relative to the server's domain. – amos Jun 17 '16 at 17:04
-
2Don't think it is going to work if path is in a jar, will give this error on toURI conversion: java.lang.IllegalArgumentException: URI is not hierarchical – tribbloid Sep 03 '16 at 22:04
-
7Only works for single-jar file, doesn't work to extract resources from dependencies in another jar – tribbloid Sep 03 '16 at 22:51
-
3This is not a safe solution, because: 1. It assumes the .jar file is a local file on the same system; 2. URL.getPath() does not return a valid file name, it just returns the path portion of the URL, with all percent-escapes intact; 3. [ProtectionDomain.getCodeSource() can return null](https://docs.oracle.com/javase/9/docs/api/java/security/ProtectionDomain.html#getCodeSource--). – VGR Oct 10 '17 at 20:00
-
Thanks for the tips you mentioned. This answer is a trade-off between simplicity and capability. It does not mean to be a perfect global answer for any situation but a fast and easy solution for most cases. – user1079877 Jul 08 '19 at 21:14
The following code returns the wanted "folder" as Path regardless of if it is inside a jar or not.
private Path getFolderPath() throws URISyntaxException, IOException {
URI uri = getClass().getClassLoader().getResource("folder").toURI();
if ("jar".equals(uri.getScheme())) {
FileSystem fileSystem = FileSystems.newFileSystem(uri, Collections.emptyMap(), null);
return fileSystem.getPath("path/to/folder/inside/jar");
} else {
return Paths.get(uri);
}
}
Requires java 7+.

- 1,014
- 1
- 11
- 25
-
1Nice! I have to add though, that FileSystem is Closeable, which means that you have to close it at some point to free system resources. Of course, returned Path will become invalid immediately after that. – Kirill Gamazkov Jul 24 '18 at 08:51
-
Note that in case of a jar file the name of the resource (here _package_ + `folder`) appears to be ignored when creating the file system. Therefore `getPath` does not return `folder/path/to/...`, but only `path/to/...`. – Marcono1234 Mar 17 '19 at 23:36
Try the following.
Make the resource path "<PathRelativeToThisClassFile>/<ResourceDirectory>"
E.g. if your class path is com.abc.package.MyClass and your resoure files are within src/com/abc/package/resources/:
URL url = MyClass.class.getResource("resources/");
if (url == null) {
// error - missing folder
} else {
File dir = new File(url.toURI());
for (File nextFile : dir.listFiles()) {
// Do something with nextFile
}
}
You can also use
URL url = MyClass.class.getResource("/com/abc/package/resources/");

- 22,769
- 3
- 58
- 74
-
36Thanks for the time and effort, but this does NOT work when your code base in within a .jar file and your resources are also in that .jar File. When you are inside a .jar file, you cannot create a File() and you also cannot get a URL for that folder... I personally came to peace with it and just listed each file in an XML... I don't think you can do that for a folder inside a jar file at all... – Mostafa Zeinali Nov 07 '12 at 06:22
-
2Sorry that your having problems. However, it does actually work when your code base is in a jar file and your resources are also in that jar file. Your are not creating a File() on disk - you are reading the File within the jar file into java memory. Note that the ClassLoader is quite happy to treat a jar file equivalent to a directory on disk. Here's the details from the source: – Glen Best Nov 07 '12 at 11:43
-
Thread.currentThread().getContextClassLoader().getResource( "Hello.txt" ); – Glen Best Nov 07 '12 at 12:32
-
1Just ran the code on a jar and got the error...oops. V sorry, my bad. Need to handle jar URL path with "File:...!/dir1/dir2...". Two fixes: http://stackoverflow.com/questions/1429172/how-do-i-list-the-files-inside-a-jar-file OR String jarPath = dirURL.getPath().substring(5, dirURL.getPath().indexOf("!")); JarFile jar = new JarFile(URLDecoder.decode(jarPath, "UTF-8")); Enumeration
entries = jar.entries(); while(entries.hasMoreElements()) { // do something } – Glen Best Nov 08 '12 at 05:12 -
Yup... I guess that works... But.. Here's the catch, When your program starts, the classes and resources in the jar are loaded into the ram... when you use that ZipStream, It's like you are doing unnecessary IO, because your resources are already on the ram, or maybe I'm wrong, maybe the resources are not loaded until a getResourceAsStream is called. In that case, this approach is not only practical, but also efficient... So... I guess we can call "problem solved" on this one... Thanks a million for your kindness and attention Glen... – Mostafa Zeinali Dec 04 '12 at 13:44
-
-
Pardon me, a typo. Left off .toURI(). Corrected above. From internet RFCs, every URL is a URI. In this case, the URL was obtained via getResource(), which uses the ClassLoader to access a file location - so it is a "file:" URL. Hence calling .toURI() gives a "file:" URI which can be used by File(uri) constructor. :) – Glen Best Mar 11 '14 at 02:19
-
1Sorry, but the URL from getResource() is NOT, I repeat NOT, guaranteed to be a file: url ... This can be any URL. Don't break existing abstractions! – Peter Kriens Jun 17 '14 at 18:01
-
3From the javadoc it's obvious that the method is not ALWAYS guaranteed to return a file under all circumstances. BUT, if you actually read the Q, the OP is 100% guaranteed to be working with files and folders by construction. The Q is asking to get access to directories and files - this is more specific that the generalised abstraction of the API. Conversion to file is appropriate and correct to meet the need. Please read the Q properly before posting such strongly contrary comments. Cheers. – Glen Best Jun 20 '14 at 03:31
-
9The OP isn't working with files and directories. He is working with resources in a JAR file. Resources in a JAR file are not files or directories and cannot be listed with the `File` class. This code does not work with resources inside a JAR file. Period. – user207421 Jul 20 '15 at 20:01
-
This does not work when running using code and resources contained inside a jar file. – Morgan Kenyon May 20 '16 at 17:15
-
I tried this by running it from filesystem and it is working but from inside jar I get `java.lang.IllegalArgumentException: URI is not hierarchical` exception – AaA Aug 03 '19 at 12:52
I know this is many years ago . But just for other people come across this topic.
What you could do is to use getResourceAsStream()
method with the directory path, and the input Stream will have all the files name from that dir. After that you can concat the dir path with each file name and call getResourceAsStream for each file in a loop.

- 10,999
- 12
- 40
- 49

- 143
- 2
- 8
-
11This works well unless you plan on jarring things up, as it turns out. – Tustin2121 Feb 20 '18 at 23:16
-
1I think this should be the accepted solution since its clean and does not require handling jar and IDE versions in separate cases. Although I'm not sure why getResource does not find the folder but getResourceAsStream does. – Raghuram Onti Srinivasan Sep 16 '19 at 23:07
-
1But you cannot get the file name from input stream of the folder. https://stackoverflow.com/a/21402828/5777189 – BabyishTank Mar 11 '22 at 05:48
I had the same problem at hands while i was attempting to load some hadoop configurations from resources packed in the jar... on both the IDE and on jar (release version).
I found java.nio.file.DirectoryStream
to work the best to iterate over directory contents over both local filesystem and jar.
String fooFolder = "/foo/folder";
....
ClassLoader classLoader = foofClass.class.getClassLoader();
try {
uri = classLoader.getResource(fooFolder).toURI();
} catch (URISyntaxException e) {
throw new FooException(e.getMessage());
} catch (NullPointerException e){
throw new FooException(e.getMessage());
}
if(uri == null){
throw new FooException("something is wrong directory or files missing");
}
/** i want to know if i am inside the jar or working on the IDE*/
if(uri.getScheme().contains("jar")){
/** jar case */
try{
URL jar = FooClass.class.getProtectionDomain().getCodeSource().getLocation();
//jar.toString() begins with file:
//i want to trim it out...
Path jarFile = Paths.get(jar.toString().substring("file:".length()));
FileSystem fs = FileSystems.newFileSystem(jarFile, null);
DirectoryStream<Path> directoryStream = Files.newDirectoryStream(fs.getPath(fooFolder));
for(Path p: directoryStream){
InputStream is = FooClass.class.getResourceAsStream(p.toString()) ;
performFooOverInputStream(is);
/** your logic here **/
}
}catch(IOException e) {
throw new FooException(e.getMessage());
}
}
else{
/** IDE case */
Path path = Paths.get(uri);
try {
DirectoryStream<Path> directoryStream = Files.newDirectoryStream(path);
for(Path p : directoryStream){
InputStream is = new FileInputStream(p.toFile());
performFooOverInputStream(is);
}
} catch (IOException _e) {
throw new FooException(_e.getMessage());
}
}

- 2,607
- 5
- 20
- 37
-
This worked fine for me. Only I switched the 'Path jarFile = Paths.get(jar.toString().substring("file:".length()));' with 'Path jarFile = Paths.get(jar.toURI());' to get it to work in Windows. Also used a try with resource statement for the FileSystem object. – Jarle Jacobsen Feb 06 '19 at 14:39
-
If you are using Spring you can use org.springframework.core.io.support.PathMatchingResourcePatternResolver
and deal with Resource
objects rather than files. This works when running inside and outside of a Jar file.
PathMatchingResourcePatternResolver r = new PathMatchingResourcePatternResolver();
Resource[] resources = r.getResources("/myfolder/*");
Then you can access the data using getInputStream
and the filename from getFilename
.
Note that it will still fail if you try to use the getFile
while running from a Jar.

- 31
- 1
Another solution, you can do it using ResourceLoader
like this:
import org.springframework.core.io.Resource;
import org.apache.commons.io.FileUtils;
@Autowire
private ResourceLoader resourceLoader;
...
Resource resource = resourceLoader.getResource("classpath:/path/to/you/dir");
File file = resource.getFile();
Iterator<File> fi = FileUtils.iterateFiles(file, null, true);
while(fi.hasNext()) {
load(fi.next())
}

- 2,622
- 24
- 21
As the other answers point out, once the resources are inside a jar file, things get really ugly. In our case, this solution:
https://stackoverflow.com/a/13227570/516188
works very well in the tests (since when the tests are run the code is not packed in a jar file), but doesn't work when the app actually runs normally. So what I've done is... I hardcode the list of the files in the app, but I have a test which reads the actual list from disk (can do it since that works in tests) and fails if the actual list doesn't match with the list the app returns.
That way I have simple code in my app (no tricks), and I'm sure I didn't forget to add a new entry in the list thanks to the test.

- 9,008
- 3
- 65
- 81
Below code gets .yaml files from a custom resource directory.
ClassLoader classLoader = this.getClass().getClassLoader();
URI uri = classLoader.getResource(directoryPath).toURI();
if("jar".equalsIgnoreCase(uri.getScheme())){
Pattern pattern = Pattern.compile("^.+" +"/classes/" + directoryPath + "/.+.yaml$");
log.debug("pattern {} ", pattern.pattern());
ApplicationHome home = new ApplicationHome(SomeApplication.class);
JarFile file = new JarFile(home.getSource());
Enumeration<JarEntry> jarEntries = file.entries() ;
while(jarEntries.hasMoreElements()){
JarEntry entry = jarEntries.nextElement();
Matcher matcher = pattern.matcher(entry.getName());
if(matcher.find()){
InputStream in =
file.getInputStream(entry);
//work on the stream
}
}
}else{
//When Spring boot application executed through Non-Jar strategy like through IDE or as a War.
String path = uri.getPath();
File[] files = new File(path).listFiles();
for(File file: files){
if(file != null){
try {
InputStream is = new FileInputStream(file);
//work on stream
} catch (Exception e) {
log.error("Exception while parsing file yaml file {} : {} " , file.getAbsolutePath(), e.getMessage());
}
}else{
log.warn("File Object is null while parsing yaml file");
}
}
}

- 540
- 8
- 20

- 59
- 1
Took me 2-3 days to get this working, in order to have the same url that work for both Jar or in local, the url (or path) needs to be a relative path from the repository root.
..meaning, the location of your file or folder from your src
folder.
could be "/main/resources/your-folder/" or "/client/notes/somefile.md"
Whatever it is, in order for your JAR file to find it, the url must be a relative path from the repository root.
it must be "src/main/resources/your-folder/" or "src/client/notes/somefile.md"
Now you get the drill, and luckily for Intellij Idea users, you can get the correct path with a right-click on the folder or file -> copy Path/Reference.. -> Path From Repository Root (this is it)
Last, paste it and do your thing.

- 555
- 4
- 15
Simple ... use OSGi. In OSGi you can iterate over your Bundle's entries with findEntries and findPaths.

- 15,196
- 1
- 37
- 55
-
14If it involves OSGI I'd hardly call it 'simple'. But if you happen to already be using OSGI... yeah sure. But suggesting to move to OSGI just to solve this particular problem seems a bit too much. – Kris Sep 09 '16 at 18:52
-
OSGi also solves many other problems and nowadays it is very easy to get started. See the OSGi enRoute tutorials – Peter Kriens Sep 09 '16 at 19:56
-
I would stay away from OSGi unless you're already required to use it. Over designed Bloatware that solves the deployment problems of the 90s IMO. – user2337270 Dec 13 '17 at 00:03
Inside my jar file I had a folder called Upload, this folder had three other text files inside it and I needed to have an exactly the same folder and files outside of the jar file, I used the code below:
URL inputUrl = getClass().getResource("/upload/blabla1.txt");
File dest1 = new File("upload/blabla1.txt");
FileUtils.copyURLToFile(inputUrl, dest1);
URL inputUrl2 = getClass().getResource("/upload/blabla2.txt");
File dest2 = new File("upload/blabla2.txt");
FileUtils.copyURLToFile(inputUrl2, dest2);
URL inputUrl3 = getClass().getResource("/upload/blabla3.txt");
File dest3 = new File("upload/Bblabla3.txt");
FileUtils.copyURLToFile(inputUrl3, dest3);

- 735
- 4
- 9
- 21
-
1Hi, thanks for the answer, but, you see, you needed to know the name of each file inside that folder when writing the code; and you had to name each one explicitly. What I was looking for was a method for iterating on the files inside the folder, and getting their names on runtime, so I could add resources to the folder, without changing the code, knowing the code will process them too. Thanks for your time though. :3 – Mostafa Zeinali Nov 04 '15 at 19:41