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
How to Assert That a Certain Exception Is Thrown in Junit Tests
"Expected Begin_Object But Was String At Line 1 Column 1"
Java Swing Revalidate() VS Repaint()
Does a Lambda Expression Create an Object on the Heap Every Time It's Executed
Best Implementation For Hashcode Method For a Collection
Getting Hold of the Outer Class Object from the Inner Class Object
Java Error: Comparison Method Violates Its General Contract
Simpledateformat Ignoring Month When Parsing
Finding the Max/Min Value in an Array of Primitives Using Java
Sort Objects in Arraylist by Date
Including Dependencies in a Jar With Maven
Arrays.Aslist() Not Working as It Should
How to Handle Cors Using Jax-Rs With Jersey
Questions About Java'S String Pool
How to Add Blank Page in Digitally Signed Pdf Using Java
Swing: Link Toggle Buttons Together With a Button Group, Along With Corresponding Menu Items