0

I try building a texture class for LWJGL 3 in Java.

My loadTexture function looks like this:

   public static Texture loadTexture(String filename) {
        int id = -1;

        try {
            File texture = new File(filename);

            if (!texture.exists()) {
                System.err.println("File '" + filename + "' does not exist.");
                return null;
            }

            // crash in following line
            InputStream stream = ClassLoader.getSystemResource(filename).openStream(); 
            PNGDecoder decoder = new PNGDecoder(stream);

            // Some code between here

            return new Texture(id, new Vector2i(decoder.getWidth(), decoder.getHeight()));
        } catch (IOException e) {
            e.printStackTrace();
            return new Texture(id, new Vector2i());
        }
    }

The stacktrace is following:

Exception in thread "main" java.lang.NullPointerException
    at org.citynopolisproject.graphics.Texture.loadTexture(Texture.java:49)
    at org.citynopolisproject.Game.<init>(Game.java:30)
    at org.citynopolisproject.Game.<init>(Game.java:33)
    at org.citynopolisproject.Game.main(Game.java:188)

The location of the file is: citynopolisproject/res/splash.png and the source file of the Texture.java (if needed) is stored in citynopolisproject/src/org/citynopolisproject/graphics.

But I don't get why it crashes and throws a NPE. You have any ideas?

Greetings

  • Possible duplicate of [What is a NullPointerException, and how do I fix it?](https://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – jrook Dec 04 '17 at 20:54
  • Obviously not. I know how to handle them. But there must be an error at ClassLoader.getSystemResource("here the existing file"), I also tried Texture.class.getResourceAsStream() and Texture.class.getClassLoader().getResourceAsStream(filename). But the code above gave less stacktrace –  Dec 04 '17 at 20:59
  • Why not `new FileInputStream(texture)`, as you already checked that file to exist? – Izruo Dec 04 '17 at 21:02
  • Well that writes a hs_err_pid*.log caused by a EXCEPTION_ACCESS_VIOLATION. Im new to Java, shipped from C++ which is not that easy. –  Dec 04 '17 at 21:05
  • 1
    Bit documentation of ClassLoader.getSystemResource: `Returns: A URL object for reading the resource, or null if the resource could not be found.` I guess your class is not found. – Oleksandr Bondarchuk Dec 04 '17 at 21:07
  • But I did not find any explaining sample code for using ClassLoader.getSystemResource(), ClassName.class.getResourceAsStream() and Texture.class.getClassLoader().getResourceAsStream() What do I have to do? folder 'res' with the file exists within the project. –  Dec 04 '17 at 21:11
  • What is passed as `filename`? What is your project structure (where is that file located)? – Pshemo Dec 04 '17 at 21:12
  • I pass a new String containing "res/splash.png". the location of the file is: citynopolisproject/res/splash.png and the source file of the Texture.java (if needed) is stored in citynopolisproject/src/org/citynopolisproject/graphics. But that makes me wonder why that should be a problem. I used the same path (for another png) to change my window icon. –  Dec 04 '17 at 21:13
  • Since I can't reproduce your problem all I can offer is a guess. Lets try with changing content of `filename` to `/res/splash.png` (add `/` at start). – Pshemo Dec 04 '17 at 21:23
  • 2
    files are searched starting from the current working directory (where java was started); resources are searched using the path to load classes (CLASSPATH) - don't mix both. Maybe you can use `ImageIO` to read the File! – user85421 Dec 04 '17 at 21:23
  • Using `res/splash.png` does not do any changes. I also mentioned the classpath thing but it gave me another error while adding the res folder. Is it possible to avoid using it with .classpath? –  Dec 04 '17 at 21:28
  • Possibly related: [Loading image resource](https://stackoverflow.com/q/9864267) – Pshemo Dec 04 '17 at 21:32
  • Resource and file do not have the 'same meaning/function'; `get*Resource` should mostly be used for reading from a JAR file (or network?) – user85421 Dec 04 '17 at 21:32
  • Okay, that's good to know. I don't want to read it from a jar file. I want to read a standalone png file as its own to the InputStream. What possibilities may exists for doing this? –  Dec 04 '17 at 21:38

1 Answers1

0

The issue (I suspsect) is that ClassLoader.getSystemResource(filename) is returning null. This could be because the file you are looking for is not on the classpath or because the classloader can't find the resource by the name you reference it.

In order to help we'd need to know more about the structure of your project. Where is this file you are looking for and is this being run in a Jar file?

You may need to look up more info on how to reference resources on the classpath. And remember that once you build the jar you wont be able to reference it with new File(filename) normally.

EDIT

You most likely do not want to bypass getting your resource from that classpath. If you are ever going to jar this program then you should be using something that will work even after it has been jarred.

xtratic
  • 4,600
  • 2
  • 14
  • 32
  • As mentioned in the question's comment section, I may quote: " I pass a new String containing "res/splash.png". the location of the file is: citynopolisproject/res/splash.png and the source file of the Texture.java (if needed) is stored in citynopolisproject/src/org/citynopolisproject/graphics. But that makes me wonder why that should be a problem. I used the same path (for another png) to change my window icon. " Is it possible to avoid the use of classpath? Does there exists another function to bypass classpath? –  Dec 04 '17 at 21:33
  • @DanielH Please edit your question to include these paths, key information should be in the question itself and not in the comments. – xtratic Dec 04 '17 at 21:44
  • Yes, `ClassLoader.getSystemResource(filename);` actually returns null. –  Dec 04 '17 at 22:12
  • @DanielH Could you go into your file system, find your project, and double check that the file is there in the bin at the path you are referencing? – xtratic Dec 04 '17 at 22:26
  • Does the res folder have to be in the bin folder while in debugging mode in eclipse? –  Dec 05 '17 at 07:13
  • @DanielH While running in Eclipse, debug or not, I believe that ClassLoader.getSystemResource() will only look in the bin. – xtratic Dec 05 '17 at 13:17