Problems while loading resources form a jar file

Hi,

I intended to post about a porblem with my litte Tileengine but when putting a testcase together i got an other problem while making a nice webstart for you.

I’m using Eclipse for development and load my Images (located in a sub folder “res/”) like:


public BufferedImage loadImage(String ref) {
... 
  BufferedImage source = null, target = null;
  java.io.File url = new java.io.File(ref);
  try {
    source = ImageIO.read( url );
  }
  catch( IOException ioe )  {
    System.err.print( "Error while loading '" + ref + "': " );
    ioe.printStackTrace();
  }
...
}

where String ref is something like “res/box.png”

java.io.File url = new java.io.File(ref); won’t work out for jars so after searching the web a bit I tried:
java.net.URL url = ((java.net.URLClassLoader)ResourceLoader.class.getClassLoader()).findResource( ref );
java.net.URL url = this.getClass().getClassLoader().getResource(ref);
java.net.URL url = Thread.currentThread().getContextClassLoader().getResource(ref);

non of them will work neither directly in eclips nor exported as jar file and I don’t have any ideas left.
Maybe you can give me a hint in the right direction.

The full testcase (including Eclipse project files) can be found here (38kb jar file which will not run of course the problems mentioned above).

You can use ImageIO.read(), that surely works… I would gave you link to method I created for loading and creating compatible images, but it has misteriusly disappeared from Shared Code section. Here it is directly, for your purposes you’ll need to modify class stuff and/or remove static :


	/** load image from PATH and make it compatible so it can be accelerated
     * @author Kova
     * @param path - relative path to image, ex.: "images/some_image.png"
     * @param image_type - type of BufferedImage
     * @return compatible loaded BufferedImage or null if reading fails
     * for now it's fail-fast and uses System.exit() on failure to load an image
     * @see Transparency.OPAQUE, .BITMASK, .TRANSLUCENT
     */
	public static BufferedImage loadAndCreateCompatibleImage(String path, int image_type) {
		URL url = null;
	    try {
	    	url = Viktorije.class.getClassLoader().getResource(path);
            GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
            BufferedImage temp1_bfimg = ImageIO.read(url);
            BufferedImage temp2_bfimg = gc.createCompatibleImage(temp1_bfimg.getWidth(), temp1_bfimg.getHeight(), image_type);
            temp2_bfimg.getGraphics().drawImage(temp1_bfimg, 0, 0, null);
	        return temp2_bfimg;
	    } catch (Exception e) {
	    	System.out.println("Error loading image: " + path + " " + url);
	    	System.exit(0);
	    	return null;
	    }
	}

just use


URL url= this.getClass().getResource(res);

and make sure you start your res-path with a ‘/’, e.g. “/res/image.png”. This loads the resource from the current classpath, so in eclipse, your “res” folder has to be copied to the compiled classes or somewhere beneath your classpath. In your jar, the “res” folder has to be a toplevel folder in the archive.

? without leading ‘/’ it works just fine, in eclipse and in jar

Thank you both.

URL url= this.getClass().getResource(res); will do fine for me w/ leading ‘/’.
ResourceLoader.class.getClassLoader().getResource(path); will do fine for me w/o leading ‘/’.

Only if you compile into the default package, since resources are loaded relative (kind of):
http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Class.html#getResource(java.lang.String)