0

First off, I would like to address that this question is very similar to the one here:getResources() returns an empty Enumeration . I chose to ask this because mine is more of a question of JAR files, as well as because the former question has yet to be answered. In addition, this is technically a different method entirely (getResource(String) instead of getResources()). Now that that is out of the way...

I am getting a mysterious error message from my code when it is in a Runnable JAR file, yet this doesn't happen at all when I am testing the project in Eclipse. The error message is:

Exception in thread "main" java.lang.ExceptionInInitializerError
    at com.wierd0games.Under.graphics.Sprite.<clinit>(Sprite.java:13)
    at com.wierd0games.Under.main.Main.<init>(Main.java:53)
    at com.wierd0games.Under.main.Main.main(Main.java:57)
Caused by: java.lang.IllegalArgumentException: input == null!
    at javax.imageio.ImageIO.read(ImageIO.java:1388)
    at com.wierd0games.Under.graphics.SpriteSheet.load(SpriteSheet.java:27)
    at com.wierd0games.Under.graphics.SpriteSheet.<init>(SpriteSheet.java:22)
    at com.wierd0games.Under.graphics.SpriteSheet.<clinit>(SpriteSheet.java:13)
    ... 3 more

From my interpretation of this error, the problem is in my Sprite class at line 13. Here, I create my first Sprite with:

public static Sprite frog=new Sprite(0, 0, 64, SpriteSheet.frog);

Then the second part of the error means that the real problem is in the SpriteSheet class, which is called on by the initialization of frog, the Sprite object. The only time I use ImageIO.read is in the function load() {} which is:

private void load() {
    try {
        BufferedImage image=ImageIO.read(SpriteSheet.class.getResource(path));
        int w=image.getWidth();
        int h=image.getHeight();
        image.getRGB(0, 0, w, h, pixels, 0, w);
    }
    catch (IOException e) {
        e.printStackTrace();
    }
}

... in which path is a String that is "/textures/spritesheetFrog.png", because the Sprite Sheet is located in a folder named textures, and is named spritesheetFrog.png.

So if the error is saying that the input is null, am I correct in that the function getReasource(String) is returning null for some reason? Does anyone have any idea why this what is happening, why is it only happening in a Runnable JAR, and most importantly, how to fix it?


EDIT: Here is a hierarchy of my classes:

src
    com.wierd0games.under.graphics (this is a package)
        Sprite
        SpriteSheet
res
    textures
        spritesheetFrog.png

So if SpriteSheet is my calling class, why does /textures/spritesheetFrog.png not work? The first slash should make it go back to the beginning, then it should go to spritesheetFrog.png, right? If not, can someone explain why this doesn't work and what it should be?


EDIT: Just to avoid confusion, the res folder is NOT located inside the source, it is separate, but included in the build path.


EDIT: Okay, I changed my hierarchy in Eclipse so that textures was indeed under source. I thought that I would update it here as well, because I have yet to get an answer that has helped me solve that problem.

src
    com.wierd0games.under.graphics (this is a package)
        Sprite
        SpriteSheet
    textures
        spritesheetFrog.png
Community
  • 1
  • 1
SecondThread
  • 108
  • 2
  • 11
  • I guess the Runnable JAR uses a different classloader that do not support (properly?) the getResource methods. – Gábor Bakos May 25 '14 at 15:44
  • With the path you're using, `textures` should be a direct child of the `src`. See [this answer](http://stackoverflow.com/questions/23854130/eclipse-java-file-fileinputstream-vs-input-stream-when-loading-font-file/23855179#23855179) for more details – Paul Samsotha May 25 '14 at 15:44
  • Open up the jar. Where is the resource relative to the root? – Sotirios Delimanolis May 25 '14 at 15:46
  • @SotiriosDelimanolis I updated it to show the hierarchy – SecondThread May 25 '14 at 16:26
  • @peeskillet Thanks, the link was very explanatory, but I am still confused as to why what I am doing doesn't work. I have a slash at the beginning, so it should go back to res, as the link explained, right? Then it will find textures, go into that, and find spritesheetFrog.png. Is this not the correct way to do it? – SecondThread May 25 '14 at 16:29
  • 1
    In Eclipse, are `src` and `res` source folders? – Sotirios Delimanolis May 25 '14 at 16:29
  • The slash takes you to the root of the class path. In terms of pre-compile it's the `src`. There for the file structure must be `ProjectRoot/src/textures/spritesheetFrog.png` – Paul Samsotha May 25 '14 at 16:32
  • `#getResource` returns an URL which `ImageIO` probably can't read from a JAR. Have you tried it with `#getResourceAsStream`? – Hauke Ingmar Schmidt May 25 '14 at 16:37
  • @SotiriosDelimanolis Yes, they are both folders. src has the image of a folder that has a little package inside it, while res has the image of a folder with three books next to it. – SecondThread May 25 '14 at 16:38
  • `res` might be in the Build Path, but is it included when exporting to a JAR? Open your JAR with a zip explorer and check. – Sotirios Delimanolis May 25 '14 at 16:45
  • @his Replacing getResource() with getResourceAsStream() (if that is what you meant) resulted in the same error message. – SecondThread May 26 '14 at 21:40
  • @SotiriosDelimanolis I opened the JAR with 7-zip. The order is (Project)>textures>spritesheetFrog.png. Isn't this what I should have done? – SecondThread May 27 '14 at 00:48
  • If by `(Project)` you mean the root of the archive, then, yes, that is correct placement for it. – Sotirios Delimanolis May 27 '14 at 00:51
  • @peeskillet I made it so that textures is a direct child of src. (see update) It still gives me the same error – SecondThread May 27 '14 at 00:54

1 Answers1

0

By your description of the problem and the comments on your question, it seems that the res directory is not defined as a "source folder" in Eclipse. You describe the icon next to res as "three little books", which is quite peculiar as this icon implies that res is a Classpath Container. How you managed to define res as a Classpath Container is beyond me (please, tell us!), but anyway, Classpath Containers are not exported to the JAR.

You should undo whatever it is that you did to define res to the project, and redefine it properly:

  1. Create the res folder at the root of the project.
  2. Right-click it, select "Build Path" -> "Use as Source Folder"
  3. Export your JAR again.
Isaac
  • 16,458
  • 5
  • 57
  • 81
  • I'm pretty sure that is how I added it to the build path the first time, but I will try to do it again, just in case. Also, just for clarification, the res folder isn't JUST the three books, like the referenced libraries and the JRE System Libraries, it is three books (smaller than when they are the only ones on the screen), with a manila folder behind them. – SecondThread May 26 '14 at 00:56
  • How about putting a screenshot somewhere and providing a link? – Isaac May 26 '14 at 01:12
  • Great idea! Here is the link: https://sites.google.com/site/wierd0games/ludum-dare-under Also, notice that I moved the actual files to a new folder named textures so that it would be under src to try to solve the problem. The icon next to res was the same before I moved it. – SecondThread May 26 '14 at 21:48
  • @WiErD0 I have never seen this icon before in my life, and I've been developing with Eclipse ever since it was first released... what happens when you delete all files inside `res` (but keep `res` alive)? does the icon change? – Isaac May 26 '14 at 21:58
  • No, the folder textures is now deleted, even though it didn't have anything in it, and it still has the same icon. Also, I have Eclipse Kepler version, if that would make a difference. – SecondThread May 27 '14 at 00:29
  • Can you attach your `.project` and `.classpath` files? They're located at the project's root. – Isaac May 27 '14 at 00:45