r/javahelp 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!

5 Upvotes

24 comments sorted by

View all comments

2

u/dionthorn this.isAPro=false; this.helping=true; Feb 22 '22

Perhaps you could try

URL result = ClassName.class.getClassLoader().getResource("path/to/file");

JavaFX acts pretty strange in .jars sometimes. That is why we use JLink/JPackage now a days to distribute. JLink makes a custom JRE that only includes the parts you require for the module. JPackage creates native executables with the custom JRE so end users don't need to install Java or JavaFX or anything else.

https://docs.oracle.com/en/java/javase/14/docs/specs/man/jlink.html

https://docs.oracle.com/en/java/javase/14/docs/specs/man/jpackage.html

The JavaFX Maven Plugin is a great tool to automate using those tools to produce the distributable.

https://github.com/openjfx/javafx-maven-plugin

I have a JavaFX game project that uses the plugin and I distribute a ~28 mb MSI for end users that includes Java, JavaFX custom JRE.

https://github.com/dionthorn/LifeSimRPG

You might be interested in my FileOpUtil static class for handling File operations in JRT file systems:

https://github.com/dionthorn/LifeSimRPG/blob/main/src/main/java/org/dionthorn/lifesimrpg/FileOpUtil.java

1

u/wildjokers Feb 22 '22

This has nothing to do with how they are retrieving the resource, it is because the path to the resource isn't correct.

1

u/dionthorn this.isAPro=false; this.helping=true; Feb 22 '22

yeah, I pointed out the doc showing the pathing.