GetResourceAsStream returns null

I am loading a text file from a package in a compiled JAR of my Java project. The corresponding directory structure is as follows:

/src/initialization/Lifepaths.txt 

Code for downloading the file:

 public class Lifepaths { public static void execute() { System.out.println(Lifepaths.class.getClass(). getResourceAsStream("/initialization/Lifepaths.txt")); } private Lifepaths() {} //This is temporary; will eventually be called from outside public static void main(String[] args) {execute();} } 

The listing will always print null no matter what i use. I'm not sure why this did not work, so I also tried:

  • "/src/initialization/Lifepaths.txt"
  • "initialization/Lifepaths.txt"
  • "Lifepaths.txt"

None of these works. I have read questions so far on this topic, but none of them have been helpful - they usually just say they upload files using the root path that I already do. This or just download the file from the current directory (just load filename ), which I also tried. The file is compiled in the JAR at the appropriate location with the appropriate name.

How to solve this?

+159
java file-io resources
May 15 '13 at 16:37
source share
13 answers

Lifepaths.class.getClass().getResourceAsStream(...) loads resources using the system class loader, it obviously fails because it does not see your JARs

Lifepaths.class.getResourceAsStream(...) loads resources using the same classloader that loaded the Lifepaths class, and it must have access to resources in your JARs

+138
May 15 '13 at 17:06
source share

The rules are as follows:

  • check the location of the file you want to load inside the JAR (and therefore also make sure that it is actually added to the JAR)
  • use either the absolute path: the path starts in the root of the JAR
  • use relative path: the path begins in the package directory of the class that you call getResource / getResoucreAsStream

And try:

 Lifepaths.class.getResourceAsStream("/initialization/Lifepaths.txt") 

instead

 Lifepaths.class.getClass().getResourceAsStream("/initialization/Lifepaths.txt") 

(not sure if that matters, but the former will use the correct ClassLoader / JAR, while I'm not sure with the latter)

+54
May 15 '13 at 16:50
source share

Thus, there are several ways to get a resource from a jar, and each of them has a slightly different syntax where the path must be given in different ways.

The best explanation I've seen is an article from JavaWorld . I will describe here, but if you want to know more, you should check out the article.

Methods

1) ClassLoader.getResourceAsStream() .

Format: "/" - split names; no leading "/" (all names are absolute).

Example: this.getClass().getClassLoader().getResourceAsStream("some/pkg/resource.properties");

2) Class.getResourceAsStream()

Format: "/" - split names; the leading "/" indicates absolute names; all other names refer to the package of the class

Example: this.getClass().getResourceAsStream("/some/pkg/resource.properties");

+43
May 15 '13 at 17:12
source share

Do not use absolute paths, make them relative to the resource directory in your project. Quick and dirty code displaying the contents of MyTest.txt from resource resources.

 @Test public void testDefaultResource() { // can we see default resources BufferedInputStream result = (BufferedInputStream) Config.class.getClassLoader().getResourceAsStream("MyTest.txt"); byte [] b = new byte[256]; int val = 0; String txt = null; do { try { val = result.read(b); if (val > 0) { txt += new String(b, 0, val); } } catch (IOException e) { e.printStackTrace(); } } while (val > -1); System.out.println(txt); } 
+14
Jul 16 '14 at 15:58
source share

You might want to try this to get the stream. First get the url and then open it as a stream.

 URL url = getClass().getResource("/initialization/Lifepaths.txt"); InputStream strm = url.openStream(); 

I had a similar question: Reading a txt file from a jar fails, but reading images works

+9
May 26 '13 at 20:55
source share

There seems to be a problem with the ClassLoader you are using. Use contextClassLoader to load the class. This is regardless of whether it is in a static / non-stationary method

Thread.currentThread().getContextClassLoader().getResourceAsStream ......

+7
Sep 27 '15 at 1:56
source share

I found myself in a similar problem. Since I use maven, I needed to update pom.xml to include something like this:

  ... </dependencies> <build> <resources> <resource> <directory>/src/main/resources</directory> </resource> <resource> <directory>../src/main/resources</directory> </resource> </resources> <pluginManagement> ... 

Pay attention to the resource tag to indicate where this folder is located. If you have nested projects (for example, me), you may want to get resources from other areas, and not just in the module in which you work. This helps reduce the persistence of the same file in each repo if you use similar configuration data.

+4
Nov 08 '16 at 0:12
source share

I don’t know if I need help, but in my case I had my own resource in the / src / folder and I got this error. Then I moved the image to the bin folder and fixed the problem.

+2
Jan 05 '15 at 18:53
source share

Make sure your resource directory (for example, "src") is in your class path (make sure that it is the source directory in the build path in eclipse).

Make sure clazz is loaded from the main classloader.

Then, to download src / initialization / Lifepaths.txt, use

 clazz.getResourceAsStream("/initialization/Lifepaths.txt"); 

Why: clazz.getResourcesAsStream(foo) looks for foo from the class clazz class compared to the clazz class it lives in. The leading "/" forces it to load from the root of any directory in the classpath clazz.

If you are not in a container of some kind, such as Tomcat, or are doing something directly with ClassLoaders, you can simply consider your eclipse / command line class path as the only classloader class path.

+2
Jul 21 '15 at 1:33
source share

What worked for me was to add the file to My Project / Java Resources / src and then use

 this.getClass().getClassLoader().getResourceAsStream(myfile.txt); 

I did not need to explain adding this file to the path (adding it to / src does this apparently)

0
Dec 16 '15 at 22:43
source share

In my case, nothing worked if I did not remove the spaces from the file names ...

0
04 Oct '18 at 13:14
source share

The default JVM class loader will first use the parent class loader: deletegate-parent-classloader .

Lifepaths.class.getClass() classes Lifepaths.class.getClass() is a bootstrap classloader , so getResourceAsStream will only search for $ JAVA_HOME, regardless of the user-provided classpath . Obviously, Lifepaths.txt does not exist.

Lifepaths.class is a system classpath classloader , so getResourceAsStream will look for a custom classpath and Lifepaths.txt there.

When using java.lang.Class#getResourceAsStream(String name) , a name that does not start with '/' will be added with package name as the prefix. If you want to avoid this, please use java.lang.ClassLoader#getResourceAsStream . For example:

 ClassLoader loader = Thread.currentThread().getContextClassLoader(); String resourceName = "Lifepaths.txt"; InputStream resourceStream = loader.getResourceAsStream(resourceName); 
0
Jul 09 '19 at 9:37
source share

@Emracool ... I would suggest you an alternative. Since you are trying to download a * .txt file. It's better to use FileInputStream() rather than the annoying getClass().getClassLoader().getResourceAsStream() or getClass().getResourceAsStream() . At least your code will execute correctly.

-12
Apr 23 '14 at 9:19
source share



All Articles