r/javahelp • u/sparkless12 • Feb 22 '22
Solved getResourceAsStream() == null when run from JAR
hello!
I have line of code such as this:
final Image roll_bg = new Image(this.getClass().getResourceAsStream("../resources/roll_bg.png"));
in IDE image is found and is rendered on canvas as expected, when exported to JAR, run ends with error. For JAR runs then, I did most hacky thing possible to extract what is wrong like so:
URL path = App.class.getResource("App.class");
if (path.toString().contains("jar")) {
PrintStream ps = new PrintStream("./log.txt");
System.setErr(ps);
System.setOut(ps);
System.out.println("Stream OUT: rerouted!");
System.err.println("Stream ERR: rerouted!");
}
and log.txt says that InputStream is null (presumably did not found resource)
Caused by: java.lang.NullPointerException: Input stream must not be null
at javafx.graphics/javafx.scene.image.Image.validateInputStream(Unknown Source)
at javafx.graphics/javafx.scene.image.Image.<init>(Unknown Source)
at com.engine.Engine.<init>(Engine.java:32)
at com.engine.Engine.get(Engine.java:94)
at com.App.start(App.java:60)
most online resources point to this method being able to reach resources from within JAR, does not work for me though. Thank you for any help offered!
4
Upvotes
1
u/wildjokers Feb 22 '22 edited Feb 22 '22
When accessing it via getResourceAsStream you are loading the resource from the classpath. You want the resource (in your case an image) to be on the classpath at the same location regardless if you are running from your IDE or from a jar file. In your case the path is not correct in the jar file.
Do you have a resources directory in your jar file? Most build tools by default will copy the contents of the resources directory directly to the root of the jar file (both maven and gradle will do this). So I highly doubt you have a resources directory in the jar file. Also the relative path
../would also be odd. Best to access it via an absolute path from the root of the jar.So the correct path to your image will be
getResourceAsStream("/roll_bg.png").Then in your IDE you want the contents of the resources directory on the classpath but not the resource directory itself. I am not sure which IDE you are using but IntelliJ will happily configured itself from a maven or gradle build. And since maven and gradle put the contents of the resources directory on the classpath it will work from the IDE too.
By the way this is a very common problem for beginners.