Danila Maximov
Danila Maximov

Reputation: 3

Problem getting resources after building a .jar

If you run the application from the idea, everything works correctly, it finds the resources. If I make an artifact .jar, there is an error. All files are present, what's the problem?

fs = new FileInputStream(Shader.class.getClassLoader().getResource(sourceVertex).getFile().replaceFirst("/", ""));
sourceVertex = new String(fs.readAllBytes());

java.exe -jar OpenGL.jar OUT:

java.io.FileNo tFoundException:file:E:\IdeaProjects\MYPROJECTS\OpenGL\out\artifacts\OpenGL_jar\OpenGL.jar!\engine\vs.glsl
        at java.base/java.io.FileInputStream.open0(Native Method)
        at java.base/java.io.FileInputStream.open(FileInputStream.java:219)
        at java.base/java.io.FileInputStream.<init>(FileInputStream.java:157)
        at java.base/java.io.FileInputStream.<init>(FileInputStream.java:112)
        at en.toshaessential.timusengine.render.Shader.init(Shader.java:29)
        at en.toshaessential.timusengine.render.Shader.<init>(Shader.java:23)
        at en.toshaessential.timusengine.render.Engine.init(Engine.java:65)
        at en.toshaessential.timusengine.render.Engine.<init>(Engine.java:55)
        at en.toshaessential.timusengine.boot.Application.main(Application.java:11)
Exception in thread "main" java.lang.NullPointerException
        at en.toshaessential.timusengine.render.Shader.init(Shader.java:37)
        at en.toshaessential.timusengine.render.Shader.<init>(Shader.java:23)
        at en.toshaessential.timusengine.render.Engine.init(Engine.java:65)
        at en.toshaessential.timusengine.render.Engine.<init>(Engine.java:55)
        at en.toshaessential.timusengine.boot.Application.main(Application.java:11)

I also noticed that when I search for files I search in OpenGL.jar! and not in OpenGL.jar. Why so?

I wanted to build a .jar application and run it

Upvotes: 0

Views: 51

Answers (1)

rzwitserloot
rzwitserloot

Reputation: 102795

FileInputStream works on files. Separately that's not how you deal with resources, and that's not how you read files in, and this isn't how to use getResource. Here's how to do it right:

String sourceVertex = "foo.png"; // if foo.png is in the same dir as shader class
String sourceVertex = "/imgs/foo.png"; // if it's in a dir named 'imgs' in the root of the jar

try (var in = Shader.class.getResourceAsStream(sourceVertex)) {
  sourceVertex = new String(in.readAllBytes(), StandardCharsets.UTF_8);
}

This:

  • Uses try-with to avoid the memory leak.
  • Avoids the strictly inferior getClassLoader() - that fails in exotic circumstances and is needless typing.
  • avoids FileInputStream, which doesn't work except on literally files.
  • Sets charset encoding, which you should always do (or, target java17+ only with --release 17, where UTF_8 is now the default).

Upvotes: 1

Related Questions