1

So I've tried various reading various fixes for this problem on stack exchange most say to use getResourceAsStream() method, which I have done. This is my Resource input method for the Jar .

import java.io.InputStream;

    public class ResourceLoader {
        public static InputStream load(String path){
    InputStream input = ResourceLoader.class.getResourceAsStream(path);
    if(input == null){
        input = ResourceLoader.class.getResourceAsStream("/" + path);
    }
    return input;
    }
}

This is then used in my ImageLoader class.

public class ImageLoader {

public BufferedImage load(String path){
    try {
//          return ImageIO.read(getClass().getResource(path));
        return ImageIO.read(ResourceLoader.load(path));
    } catch (IOException e) {
        e.printStackTrace();
    }
    return null;
    }
}

and the images are loaded in the main program using

ImageLoader loader = new ImageLoader();
    spriteSheet = loader.load("/spritesheet.png");

Now in eclipse the game runs and loads all images perfectly fine. But what I want to do is export it to Jar, which I have done using some tutorials and have succeeded in exporting it with the resource folder which contains my images that are used. But when I try and run the .jar file this error pops up in the cmd line.

Exception in thread "Thread-2" java,lang.IllegalArgumentException: input == null
!
    at javax.imageio.ImageIO.read<Image.IO.java:1348>
    at gfx.ImageLoader.load<ImageLoader.java:15>
    at man.Gaim.init(Game.java:100>
    at main.Game.run<Game.java:150>
    at java.lang.Thread.run<Thread.java:722>

So what I'm gathering is that the image file locations are not being read properly or I inputed them wrong somehow which is returning null and none of the images are loading. When the .Jar is run the Panel appears but nothing is painted to it and that error is given. This program does work perfectly in eclipse with no errors and all images loading.

EDIT 1: Robermann your solution for the getClass().getClassLoader().getResourceAsStream(path)) works. The only thing is I need to have the image files in a folder with the jar. For instance I have Folder: ---File.Jar ---Images.png ---ImageFolder -------More imgaes in imagefolder.png

I can load all the images when they are located like that. My actual question was when i export a .Jar the Images are also located inside is it possible to just use the images that are located inside the .jar? Or do I have to pack the imgaes in a folder alongside the jar as above, It works but i was more looking for a runnable .Jar that i could just transer to tohers without having them also need the images outside the .jar.

robermann
  • 1,722
  • 10
  • 19
user1761953
  • 47
  • 1
  • 6
  • possible duplicate of [Load images in jar file](http://stackoverflow.com/questions/18547780/load-images-in-jar-file) –  Mar 05 '14 at 17:14
  • I attempted this although I still get the same error and it does not work in eclipse. – user1761953 Mar 05 '14 at 19:25

1 Answers1

7

The question of how to load classpath resources is quite recurring, and a bit confusing for a Java newbie: some answers suggest class.getClassLoader().getResourceAsStream, others class.getResourceAsStream, although they have a slight different semantic:

  1. class.getResourceAsStream does a path translation
  2. class.getClassLoader().getResourceAsStream does not translate the path

For better show the difference, I'm going to propose the following test class, which in 4 different ways try to load the same resource (an image), only 2 working depending on the used path. The Jar content-tree is:

enter image description here

The class:

package image;

import java.io.InputStream;

public class ImageLoader {
    public static void main(String[] args ){
        String cmd = null;
        InputStream is = null;
        final String image = "save.png";

        if("test1".equals(args[0])){
            cmd = "ImageLoader.class.getClassLoader().getResourceAsStream(\""+image+"\")";
            is = ImageLoader.class.getClassLoader().getResourceAsStream(image);     //YES, FOUND


        }else if("test2".equals(args[0])){
            cmd = "ImageLoader.class.getResourceAsStream(\""+image+"\")";
            is = ImageLoader.class.getResourceAsStream(image);                      //NOT FOUND

        }else if("test3".equals(args[0])){
            cmd = "ImageLoader.class.getResourceAsStream(\"/"+image+"\")";
            is = ImageLoader.class.getResourceAsStream("/"+image);                  //YES, FOUND

        }else if("test4".equals(args[0])){
            cmd = "ImageLoader.class.getClassLoader().getResourceAsStream(\"/"+image+"\")";
            is = ImageLoader.class.getClassLoader().getResourceAsStream("/"+image); //NOT FOUND

        }else {
            cmd = " ? ";
        }

        System.out.println("With "+cmd+", stream loaded: "+(is != null));
    }
}

Run with:

java -cp resLoader.jar image.ImageLoader test4

Hope this class can help in understanding the different behaviour.

robermann
  • 1,722
  • 10
  • 19
  • That is the way the .jar is right now. The images are in the root folder unless they were in a folder like res/PNG, then they are in the .jar/PNG but otherwise they are in the root folder. – user1761953 Mar 05 '14 at 16:41
  • Pass from the classloader, of course: java.awt.Image pic = javax.imageio.ImageIO.read(getClass().getClassLoader().getResourceAsStream("spritesheet.png")) - see my answer here: http://stackoverflow.com/questions/22045718/unable-to-load-picture-from-resource/22046065#22046065 – robermann Mar 05 '14 at 16:52
  • So I attempted that although I still get the same error. this is how I implemented your example incase I did it wrong: return ImageIO.read(getClass().getClassLoader().getResourceAsStream(path)); this replaced the return ImageIO.read(ResourceLoader.load(path)); in the ImageLoader class. – user1761953 Mar 05 '14 at 17:39
  • follow the link on @jarrod's comment, or give us the path you are now using, and the .jar content's tree. – robermann Mar 05 '14 at 18:16
  • The current Path for spritesheet is "/spritesheet.png". The .jar contents tree is:
    game.jar
    ---Folder
    ---Folder
    ---Folder
    ---Png
    ------Some of the images here
    ---spritesheet.png here in the .jar root folder with some other images
    – user1761953 Mar 05 '14 at 19:19
  • you should use the path without the "/", so use ImageIO.read(getClass().getClassLoader().getResourceAsStream("spritesheet.png")) – robermann Mar 05 '14 at 20:42
  • 1
    This helped me a lot in combination with a explanation, how Eclipse handles the Classpath by default (and adding the used resource folder to it) – Jochen Birkle Jul 18 '14 at 08:36