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
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