Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

"Uncatchable" exception while loading images 1

Status
Not open for further replies.

wiser

Programmer
Jan 29, 2003
10
GB
I am trying to write an application to be launched via our intranet site using Java Web Start, and I want to store resources such as images in a separate jar file so that they can then be easily re-used in other similar apps. The resource jar file is also stored on a central server and can be accessed via either a network path or an " URL on the web server. Either can be specified in the Class-Path attribute in the manifest of the app's jar file and both work fine as long as the resource jar file is there. However, I'm having trouble handling the case where it can't be found (e.g. if the network connection drops for some reason) and the images can't be loaded.
The method I use to load the images is:
Code:
	import java.awt.*;
	import java.net.URL;

	...

	private Image loadImage(String fileName)
	{
		Image img = null;
		try
		{
			// Try to load image resource
			URL url = this.getClass().getClassLoader().getResource(fileName);
			img = Toolkit.getDefaultToolkit().getImage(url);
		}
		catch(Exception ex)
		{
			// ignore
		}
		return img;
	}

If the image can't be found I want the method to simply return null and my app will either use a spacer or a default icon from the L&F. However when I launch the app (removing the resource jar first so it can't be loaded) I get the following exception and the app hangs before even displaying the GUI:
[tt]
Uncaught error fetching image:
java.lang.NullPointerException
at sun.awt.image.URLImageSource.getConnection(URLImageSource.java:99)
at sun.awt.image.URLImageSource.getDecoder(URLImageSource.java:108)
at sun.awt.image.InputStreamImageSource.doFetch(InputStreamImageSource.java:248)
at sun.awt.image.ImageFetcher.fetchloop(ImageFetcher.java:172)
at sun.awt.image.ImageFetcher.run(ImageFetcher.java:136)
[/tt]

I also tried putting an additional exception handler in the AWT event queue (by subclassing [tt]java.awt.EventQueue[/tt]), but it didn't help; I don't think just loading an image generates any AWTEvent anyway.

Any other ideas how I can catch this exception?
 
Did you check if the url object is null before reting to load the img object ?

--------------------------------------------------
Free Java/J2EE Database Connection Pooling Software
 
No, but that should be caught by the "[tt]try ... catch(Exception ex)[/tt]" block, shouldn't it?
The only thing I can think of is that [tt]Toolkit.getDefaultToolkit().getImage(url)[/tt] is firing off the [tt]ImageFetcher[/tt] listed in the stack trace in another thread which isn't handling the exception. I suppose I could add the line:
Code:
	url.openConnection();
before calling [tt]getImage[/tt]...

Yep, just tried that and it works! (Don't know why I didn't think of that before...)
Thanks a lot!
 
You should never replace a simple programmatical check (ie checking that a variable is null) with a reliance on try/catch blocks.

try/catch blocks and exceptions are very easy - but there is a massive overhead to them, and you should use them as little as possible. Checking if a variable is null is much more performant.

BTW, you'll never catch a NullPointerException with a "catch Exception" block. Consider this code @

Code:
PrintWriter pw = null;
try {
  pw.println("hello"); // cause an NPE
} catch (Exception e) {
  System.out.println("got exception");
}

This will not catch the NPE - but will bomb out.
Why ? I'm not sure, but I'm guessing that because the object's pointer is null, you are shafting memory (if you did this in C, you would cause a SIGSEGV signal and the programme would crash).

--------------------------------------------------
Free Java/J2EE Database Connection Pooling Software
 
I've removed the line
Code:
	url.openConnection();
and added an if() block:
Code:
	if(url != null)
	{
		img = Toolkit.getDefaultToolkit().getImage(url);
	}
In this case it does seem to work just as well. I wasn't sure if it would because this wouldn't cater for the case where the URL was non-null but unreachable.

I'm not sure what you mean about not being able to catch NullPointerExceptions though; I don't think that can be right, although I do take on board what you say about the overheads involved. I tried running your example code from above (using the default JVM in J2SE 1.4) and the exception was caught - I got "got exception" printed to stdout.
 
Hmmm, I see your point about that NullPointerException example ... I was sure in the past ... ho hum.

OK, to throw some more odd action into the fire, run this code. Even though 'url' is null, there is no exception thrown for me - nor any stack trace like you are seeing. Must be missing something ...

Code:
import java.io.*;
import java.net.*;
import java.awt.*;

public class TestNPE {
	public void doit() {
            URL url = this.getClass().getClassLoader().getResource("bla");
			// url is null here ...
            Image img = Toolkit.getDefaultToolkit().getImage(url);
	}

	public static void main(String args[]) {
		try {
		  new TestNPE().doit();
		} catch (Exception e) {
		  System.out.println("got exception");
		}
	}
}

--------------------------------------------------
Free Java/J2EE Database Connection Pooling Software
 
NPE is a RuntimeException, which means (amongst other things) the method throwing it needn't declare throwing it.

Since every objectreference might be null, there would be an 'throws NPE' everywhere in your code, which wouldn't be very useful.

If you write a method, and declare 'throws NPE', and throw a NPE you're able to catch it.

If it isnt't declared to be thrown, you can't catch it.

seeking a job as java-programmer in Berlin:
 
I'm not sure about that Stefan - thought that was the case, but this example seems to show it is not the case :

Code:
import java.io.*;

public class TestNPE {
	public void doit() {
		PrintWriter pw = null;
		pw.println("hello");//throw an NPE
	}

	public static void main(String args[]) {
		try {
		  new TestNPE().doit();
		} catch (Exception e) {
		  System.out.println("got exception");
		}
	}
}

--------------------------------------------------
Free Java/J2EE Database Connection Pooling Software
 
From my experience, you can catch an NPE wherever you want to, no SIGSEVs or whatever.

What I think it's happening is that the NPE is being caught inside the getImage method and the stacktrace is just being shown.

Cheers,
Dian
 
@sedj: You seem right. Your first example didn't throw a NPE,

Image img = Toolkit.getDefaultToolkit().getImage (url);

seems to be robust against a null-url.
diancecht might be rigth - they're printing the stacktrace themselves.

seeking a job as java-programmer in Berlin:
 
RuntimeException subclasses Exception, so catching Exception will catch a NPE too.

Some stuff throws subclasses of java.lang.Error which doesn't subclass Exception. When I need to know I'll catch absolutely anything, I catch Throwable which is the granddaddy of them all.

Tim
 
You can catch nullpointerexceptions, when you use something like this

try {
PrintWriter pw = null;
pw.println("hello");//throw an NPE
} catch (Throwable e) {
if (e instanceof NullPointerException) {
System.out.println("got the NPE"
}
else {
System.out.println("got another Exception"
}
}

 
tom62, you don't need that Throwable stuff - my example above shows that an NPE can be caught in a simple Exception catch ...

--------------------------------------------------
Free Java/J2EE Database Connection Pooling Software
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top