Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading a resource file from within jar

I would like to read a resource from within my jar like so:

File file; file = new File(getClass().getResource("/file.txt").toURI()); BufferedReader reader = new BufferedReader(new FileReader(file));  //Read the file 

and it works fine when running it in Eclipse, but if I export it to a jar, and then run it, there is an IllegalArgumentException:

Exception in thread "Thread-2" java.lang.IllegalArgumentException: URI is not hierarchical 

and I really don't know why but with some testing I found if I change

file = new File(getClass().getResource("/file.txt").toURI()); 

to

file = new File(getClass().getResource("/folder/file.txt").toURI()); 

then it works the opposite (it works in jar but not eclipse).

I'm using Eclipse and the folder with my file is in a class folder.

like image 990
Koi Avatar asked Dec 05 '13 00:12

Koi


People also ask

How do I view the resources folder in a JAR file?

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 .

How do I extract a resource from a JAR file?

Install an archive program. JAR files work just like ZIP files. You can use any archive program to extract them. On Windows, you can Install WinRAR 7-Zip, or WinZIP.

Can you get source code from a JAR file?

Hi, Jar files are archive files that contains of a lot of different java classes (files). You can use winzip/winrar to open the jar files and you can see those java classes in jar files. Typically you can use a Java decompiler to decompile the class file and look into the source code.


2 Answers

Rather than trying to address the resource as a File just ask the ClassLoader to return an InputStream for the resource instead via getResourceAsStream:

try (InputStream in = getClass().getResourceAsStream("/file.txt");     BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {     // Use resource } 

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:

  • How do I read a resource file from a Java jar file?
  • Java Jar file: use resource errors: URI is not hierarchical
like image 146
Drew MacInnis Avatar answered Oct 07 '22 10:10

Drew MacInnis


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.

like image 33
Juozas Kontvainis Avatar answered Oct 07 '22 09:10

Juozas Kontvainis