Getresourceasstream Returns Null

getResourceAsStream returns null

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

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

getResourceAsStream() is always returning null

To my knowledge the file has to be right in the folder where the 'this' class resides, i.e. not in WEB-INF/classes but nested even deeper (unless you write in a default package):

net/domain/pkg1/MyClass.java  
net/domain/pkg1/abc.txt

Putting the file in to your java sources should work, compiler copies that file together with class files.

Why would ClassLoader.getResourceAsStream() return null?

I solved the mystery.

The key to solving was embedding some diagnostic logging when propertiesStream is null:

String classpath = System.getProperty("java.class.path");
LOG.info("CLASSPATH: " + classpath);
ClassLoader loader = MyClientMain.class.getClassLoader();
System.out.println("ClassLoader resource path: " + loader.getResource("resource.properties"));

So when I run with the original

contextClassLoader.getResourceAsStream("resource.properties")

I receive the null pointer condition, printing:

  INFO: CLASSPATH: myproj.one-jar.jar
ClassLoader resource path: null

.

I then started suspecting something related to the "jar within a jar" as this is what the com.simontuffs.onejar essentially does (i.e. wrapping my project's jar inside a jar that contains all other library jars), so I opened myproj.one-jar.jar with 7-Zip and noted the full (absolute) path of "resource.properties":

myproj.one-jar.jar\main\myproj.jar\webapp\WEB-INF\classes\resource.properties

.

So I modified getResource("resource.properties") to:

 getResource("/main/myproj.jar/webapp/WEB-INF/classes/resource.properties")

which didn't fix the problem but printed the following upon the null pointer condition:

INFO: CLASSPATH: myproj.one-jar.jar
ClassLoader resource path: jar:file:/myproj.one-jar.jar!/main/myproj.jar!//main/myproj.jar/webapp/WEB-INF/classes/resource.properties

.

Then... divine intervention fell upon me and I had the insight (not reading any documentation that could even hint this, I swear!) that I should be using this path instead:

 getResource("/webapp/WEB-INF/classes/resource.properties")

And Voila! It works.

Whew.

getResourceAsStream returns null value

You are using and Initializing the Resource correctly.

So if it is not working than your file is either not using an relative path to its location inside the Resources folder or isn't at all inside the Resources folder.

If it is not in the Resources folder getResourceAsStream cant access it.

For example:
The Structure:

└── src
└── main
├── java
│ └── Main.java // Here you would use the your Resource for example
└── resources
└── NoImageAvailable.png

Constant declaration:

class Constant {
public static final String DEFAULT_PROFILE_PICTURE = "NoImageAvailable.png";
}

If you are using the structure this should work :).

Why is getResourceAsStream returning null?

It is all about relative vs absolute packages when calling getResourceAsStream(), you looking for something relative to whatever package Content is at as the root.

there are no "directories" on the classpath, especially inside .jar files, only packages

The best thing to use is Thread.currentThread().getContextClassloader().getResourceAsStream() with a fully qualified package without the leading /.

The reason this is best is because inside of application containers, they usually have multiple classloaders and this way you don't have to care which one your resource is loaded from.

In your case:

Thread.currentThread().getContextClassloader().getResourceAsStream("resources/generic/mouse.png");

If you still get an error with this approach your .jar isn't built like you think it is or if you are getting this from inside an IDE you probably aren't copying the contents resource/generic/ into the classpath.

Personally I always use the form:

Thread.currentThread().getContextClassLoader().getResourceAsStream("path/to/resource/file.ext"); as it always works from where ever you call it and whatever classloader you are in, and it is explicit about where it is looking to find what it is looking for.

Why does getResourceAsStream() return null when File does not exist before start of Test method?

The getResourceAsStream() method returns a stream for a resource on the classpath, using directory / index information that is cached by the classloader. If you add a resource to some directory tree or archive on the classpath after the classpath has been cached, the classloader is likely to not "see" it1.

That is most likely is what has happened in your test code.

A Java application should not be trying to treat classloader resources like a general purpose file system. Instead, use File or Path to denote files, and FileInputStream or similar to open them.


1 - The actual behavior does not appear to be specified in the javadocs for ClassLoader, etcetera. My description is based on the observed / reported behavior of some Java implementations.

ClassLoader getResourceAsStream returns null

If it's in the same package use

InputStream is = Driver.class.getResourceAsStream("myconfig.txt");

The way you have it

InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("myconfig.txt");

It's looking for the file in the root of the classpath. You could use

InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("com/me/myapp/myconfig.txt");

The rules for searching are explained in the javadoc of ClassLoader#getResource(String) and the javadoc of Class#getResource(String).



Related Topics



Leave a reply



Submit