gifs in jars; I keep getting a null url
Okay, I have a jar file with the package com.marklawford in it. I also have a folder called icons holding the particular image new16.gif.
I have tried:
public ImageIcon loadIcon( String location ){
URL imgURL = ClassLoader.getSystemResource(location);
System.out.println("image url = "+ imgURL);
Toolkit toolkit = Toolkit.getDefaultToolkit();
ImageIcon img =new ImageIcon( toolkit.getImage(imgURL) );
return img ;
}
The method is part of my EditorBase class which is in the com.marklawford package and this is where I call it, but I keep getting a null value in the imgURL.
com.marklawford.EditorBase
icons\new16.gif
What am I doing wrong?
I made a few modifications to your code, it should work :)
public ImageIcon loadIcon(String location, String jarName){
String jarPath = ClassLoader.getSystemResource(jarName).toString();
URL imgURL = new URL("jar:" + jarPath + "!/" + location);
System.out.println("image url = "+ imgURL);
ImageIcon img = new ImageIcon(imgURL);
return img ;
}
What the code does (in case anyone is interested):
First, you'll note that I added a new param to your method (jarName). Since we're pulling an image out of a jar file, of course we need to know which jar file to pull from. Then we need to know where that jar file is, so we ask the classloader to find it for us. Once that's done, we make a special URL (refer to the JarURLConnection class for more info) and pass that directly to ImageIcon. So there you have it. You get an ImageIcon from an image file located in a Jar file.
-Ron
rSully at 2007-6-29 12:18:47 >

Oops, I forgot to catch the URL exception. Here's a copy from my library, so I know it works:
public ImageIcon getJarImageIcon(String imgName, String jarName)
{
URL iconURL = null;
try
{
String jarPath = ClassLoader.getSystemResource(jarName).toString();
iconURL = new URL("jar:" + jarPath + "!/" + imgName);
}
catch (Exception e){}
return new ImageIcon(iconURL);
}
rSully at 2007-6-29 12:18:47 >

Thanks for the code and the help there. I am still getting problems with null values despite using the method as you've presented it.
Is there some strange esoteric jar deployment technique I don't know about?
Currently I am just using the java -jar codegenerator.jar command to run the app, which picks up the main class no problem. The trouble is, the class loader can't seem to even find the jar as a system resource from that point on.
I have not added the jar to the classpath at all as I wanted freedom to run the app from an arbitrary location. Do I need to do this?
I'm so frustrated by this problem that I'm on the verge of turning to VB, so please, listen to this cry for help and tell me where I'm going wrong.
Ah, well, make sure the classpath is set correctly in your manifest.Class-Path: .<-- (thats a decimal point in case it's hard to read)See the Jar Trail for additonal tips on manifest values, how to include them, etc.-Ron
rSully at 2007-6-29 12:18:47 >

Hi Mark,
Since I haven't heard from you, I'll assume that you got your code working and everything is OK.
Lately, I've been doing a lot of research in this area and I'll be posting some of my findings over the weekend, but in case your code still isn't working, I have one last suggestion for you. And that is, go back to your original code. Yep, that's right, there was nothing wrong with your code, it was the seperator you used in your variable. I'm sorry I missed that one, and although the alternative code does work you probably didn't have any luck with it, due to the fundamental nature of the problem. Here's what I'm talking about, in your original post you said at the bottom:
>icons\new16.gif
And me being a Windoze guy, glossed right over that. JAR files no matter what platform they are deployed on, ALWAYS use "/" internally as the file seperator. So all you had to do was pass:
icons/new16.gif
and everything would have worked. Sorry it took more than a week to get your question filled, but I think this will do it.
-Ron
rSully at 2007-6-29 12:18:47 >

Cheers for looking back in Ron.
No, I haven't got that code to work yet and I have been through as many iterations as I could think of including the seperator.
I will go back and try it out as soon as I get a few minutes. At least now I have about four different ways of achieving the same thing and one of them is bound to work with on or t'other seperator.
I'll post again when I have tried it.
Mark
No, it still doesn't work. I don't get it, I really don't. I must be doing something fundamentally wrong.
I have included as much info below as I can think of. The manifest, the method the method as it is called and the error message produced by the failure.
Am I missing something with regard to how the getSystemResource method itself works?
MANIFEST FILE:
Manifest-Version: 1.0
Main-Class: com.marklawford.EditorBase
Created-By: 1.3.0 (Sun Microsystems Inc.)
Class-Path: .
METHOD:
public ImageIcon loadIcon( String location ){
URL imgURL = ClassLoader.getSystemResource(location);
System.out.println("image url = "+ imgURL);
Toolkit toolkit = Toolkit.getDefaultToolkit();
ImageIcon img = new ImageIcon( toolkit.getImage(imgURL) );
return img ;
}
USAGE:
file.add( menuItem( "New", desktop, "new", 'N', KeyEvent.VK_N, loadIcon("icons/new16.gif") ));
ERROR MESSAGE:
Uncaught error fetching image:
java.lang.NullPointerException
at sun.awt.image.URLImageSource.getConnection(Unknown Source)
at sun.awt.image.URLImageSource.getDecoder(Unknown Source)
at sun.awt.image.InputStreamImageSource.doFetch(Unknown Source)
at sun.awt.image.ImageFetcher.fetchloop(Unknown Source)
at sun.awt.image.ImageFetcher.run(Unknown Source)
Sorry to hear that Mark, and I agree at this point there is something fundametally wrong since I have used the code as posted sucessfully, along with the other variations and they all work. This code is a little shorter and more to the point, I'd recommend using this instead:
public ImageIcon loadIcon(String location)
{
URL img = null;
try
{
img = ClassLoader.getSystemResource(location);
}
catch (Exception e){e.printStackTrace();}
return new ImageIcon(img);
}
There is one more piece of information I'd like to see, and that's a listing of your jar contents. I have a feeling that that's where the problem lies. Could be something simple like your new16.gif is in an images folder not the icons folder. Or maybe you named the folder Icons instead of icons. Something of that nature. Java is so picky about being case-sensitive, unlike windows, such that your project will work fine outside of a jar, but not inside. I find this to be a common problem, and suspect that this is also your problem too.
-Ron
rSully at 2007-6-29 12:18:47 >

I managed with it your original method by using a forward slash in the location. Must be something wrong in your jar file, but I am no guru and still new to java.
Dustin at 2007-6-29 12:18:47 >

Thanks for sticking with me Ron,
I have just been building a table of contents for the jar file as you requested. As I looked at the table, I realised I'd made a dreadful mistake...
I saw something that I thought I had already sorted and resolved. I thought I'd managed to verify whether or not the filename had any upper case characters or not. I obviously didn't. I was looking for "icons/new16.gif" when I needed "icons/New16.gif". I didn't see it.
My thanks go to you and the others who helped me solve this (painful) problem. All the solutions offered obviously worked, and I have learned a great deal about jar files to boot.
In future, if you see one of my posts, feel free to remind me that java is case sensitive.
Thanks again,
Mark
case closed.
Excellent!!!Happy to help,-Ron
rSully at 2007-6-29 12:18:47 >
