3
BufferedImage = ImageIO.read(getClass().getResourceAsStream("/Images/player.gif"));

First of all, yes I did add the image folder to my classpath.

For this I receive the error java.lang.IllegalArgumentException: input == null!

I don't understand why the above code doesn't work. From everything I read, I don't see why it wouldn't. I've been told I should be using FileInputStream instead of GetResourceAsStream, but, as I just said, I don't see why. I've read documentation on the methods and various guides and this seems like it would work.

Edit: Okay, trying to clear some things up with regards to what I have in the classpath.

This is a project created in Eclipse. Everything is in the project folder DreamGame, including the "Images" folder. DreamGame is, of course, in the classpath. I know this works because I'm reading a text file in /Images with info on the gif earlier on in the code.

So I have: /DreamGame/Images/player.gif

Edit 2: The line that's currently in the original post is all that's being passed; no /DreamGame/Images/player.gif, just /Images/player.gif. This is from a method in the class ImagesLoader which is called when an object from PlayerSprite is created. The main class is DreamGame. I'm running the code right from Eclipse using the Run option with no special parameters

Trying to figure out how to find which class loader is loading the class. Sorry, compared to most people I'm pretty new at this.

Okay, this is what getClassLoader() gets me: sun.misc.Launcher$AppClassLoader@4ba778

getClass().getResource(getClass().getName() + ".class") returns /home/gixugif/Documents/projects/DreamGame/bin/ImagesLoader.class

The image file is being put in bin as well. To double check I deleted the file from bin, cleaned the project, and ran it. Still having the same problem, and the image file is back in bin

Gixugif
  • 33
  • 1
  • 4

2 Answers2

4

Basically, Class.getResourceAsStream doesn't do what you think it does.

It tries to get a resource relative to that class's classloader - so unless you have a classloader with your filesystem root directory as its root, that won't find the file you're after.

It sounds like you should quite possibly really have something like:

BufferedImage = ImageIO.read(getClass().getResourceAsStream("/Images/player.gif"))

(EDIT: The original code shown was different, and had a full file system path.)

and you make sure that the images are copied into an appropriate place for the classloader of the current class to pick up the Images directory. When you package it into a jar file, you'd want the Images directory in there too.

EDIT: This bit may be the problem:

First of all, yes I did add the image folder to my classpath.

The images folder shouldn't be in the classpath - the parent of the Images folder should be, so that then when the classloader looks for an Images directory, it will find it under its root.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Good to know, thanks, but it doesn't fix anything. I actually have getResourceAsStream(IMAGE_DIR + fnm) in my real code anyway. Just figured I should put what that resolves as in here. Edited original post to show this. – Gixugif Oct 31 '11 at 13:21
  • @user1022004: Well it will fix it *if the classloader is set up appropriately* with the files in an appropriate place. We have no idea how you're running this, what sort of class loader you're using etc. Note that the Images folder itself shouldn't be in the classpath - the *parent* folder should be. – Jon Skeet Oct 31 '11 at 13:25
  • Okay, sorry for the confusion. I edited again to clear things up. If there are any problems regarding the classpath now you can be sure they exist and it's not from me not being clear. – Gixugif Oct 31 '11 at 13:34
  • @Gixugif: Your final line still isn't clear - are you passing in "/DreamGame/Images/player.gif" anywhere? How are your classes being deployed? How are you running your code? – Jon Skeet Oct 31 '11 at 14:19
  • The line that's currently in the original post is all that's being passed; no "/DreamGame/Images/player.gif", just "/Images/player.gif". This is from a method in the class "ImagesLoader" which is called when an object from "PlayerSprite" is created. The main class is DreamGame. I'm running the code right from Eclipse using the "Run" option. – Gixugif Oct 31 '11 at 14:36
  • @Gixugif: And how are you running it? Which classloader is the class that's requesting the resource using? – Jon Skeet Oct 31 '11 at 14:39
  • This is what getClassLoader() gets me: "sun.misc.Launcher$AppClassLoader@4ba778", so I guess I'm using the AppClassLoader – Gixugif Oct 31 '11 at 15:13
  • @Gixugif: What does `getClass().getResource(getClass().getName())` show? – Jon Skeet Oct 31 '11 at 15:17
  • @Gixugif: Sorry, my mistake: `getClass().getResource(getClass().getName() + ".class")` – Jon Skeet Oct 31 '11 at 15:36
  • :`/home/gixugif/Documents/projects/DreamGame/bin/ImagesLoader.class` – Gixugif Oct 31 '11 at 15:41
  • @Gixugif: Okay, so *something* is copying all your classes into the `bin` directory. My guess is that it's not copying the images. This goes back to what I asked about how you're running the code, which you didn't answer. You need to make whatever you're using to build the code *also* copy the resources into the `bin` directory, I suspect. – Jon Skeet Oct 31 '11 at 15:42
  • Maybe I'm misunderstanding, or you missed where I said it, but I'm running the code in Eclipse, just with the "run" option, and I haven't specified any special parameters. The image file is being put in `bin` as well. To double check I deleted the file from `bin`, cleaned the project, and ran it. Still having the same problem, and the image file is back in `bin`. – Gixugif Oct 31 '11 at 15:54
  • @Gixugif: Right, it would have been nice to know about the Eclipse part earlier :) Is there still an Images directory under `bin`? (There should be `.../bin/Images/player.gif`) If so, it sounds like it *should* be working then. It's all case-sensitive - could that be an issue? Cna you confirm that logging `getClass().getResource("/Images/player.gif")` still prints null? – Jon Skeet Oct 31 '11 at 16:00
  • Sorry, I mentioned it in a previous comment by editing it in. Yes, it does. This might point to something though (or not?): the file `player.gif` is in `bin`, however the entire `/Images` directory (which just contains `player.gif` and a `.txt` file) is not. – Gixugif Oct 31 '11 at 16:06
  • @Gixugif: Ah - that's the problem then. It's looking for `Images` *in the `bin` directory. Either change your build path (e.g. by adding a "resources" directory in the build path and putting Images inside that) or change to just "/player.gif" in the source. – Jon Skeet Oct 31 '11 at 16:08
  • You are totally correct. Changing it to `/player.gif` in the source made it work perfectly. I have been stuck on this so long. You have my gratitude. – Gixugif Oct 31 '11 at 16:10
1

If you use resourceAsStream "/" referes to the root of the classpath entry, not to the root of the file system. looking at the path you are using this might be the reason.

If you load something from some home path you probably should use a FileInputStream. getResourceAsStream is for stuff that you deploy with your app.

Jens Schauder
  • 77,657
  • 34
  • 181
  • 348