Java unreported exception [duplicate]

While learning Java I stumble upon this error quite often. It goes like this:

Unreported exception java.io.FileNotFound exception; must be caught or declared to be thrown.

java.io.FileNotFound is just an example, I've seen many different ones. In this particular case, code causing the error is:

OutputStream out = new BufferedOutputStream(new FileOutputStream(new File("myfile.pdf")));

Error always disappears and code compiles & runs successfully once I put the statement inside try/catch block. Sometimes it's good enough for me, but sometimes not.

First, examples I'm learning from do not always use try/catch and should work nevertheless, apparently.

Whats more important, sometimes when I put whole code inside try/catch it cannot work at all. E.g. in this particular case I need to out.close(); in finally{ } block; but if the statement above itself is inside the try{ }, finally{} doesnt "see" out and thus cannot close it.

My first idea was to import java.io.FileNotFound; or another relevant exception, but it didnt help.

1

2 Answers

What you're referring to are checked exceptions, meaning they must be declared or handled. The standard construct for dealing with files in Java looks something like this:

InputStream in = null;
try { in = new InputStream(...); // do stuff
} catch (IOException e) { // do whatever
} finally { if (in != null) { try { in.close(); } catch (Exception e) { } }
}

Is it ugly? Sure. Is it verbose? Sure. Java 7 will make it a little better with ARM blocks but until then you're stuck with the above.

You can also let the caller handle exceptions:

public void doStuff() throws IOException { InputStream in = new InputStream(...); // do stuff in.close();
}

although even then the close() should probably be wrapped in a finally block.

But the above function declaration says that this method can throw an IOException. Since that's a checked exception the caller of this function will need to catch it (or declare it so its caller can deal with it and so on).

4

Java's checked exceptions make programmers address issues like this. (That's a good thing in my opinion, even if sweeping bugs under the carpet is easier.)

You should take some appropriate action if a failure occurs. Typically the handling should be at a different layer from where the exception was thrown.

Resource should be handled correctly, which takes the form:

acquire();
try { use();
} finally { release();
}

Never put the acquire() within the try block. Never put anything between the acquire() and try (other than a simple assign). Do not attempt to release multiple resources in a single finally block.

So, we have two different issues. Unfortunately the Java syntax mixes up the two. The correct way to write such code is:

try { final FileOutputStream rawOut = new FileOutputStream(file); try { OutputStream out = new BufferedOutputStream(rawOut); ... out.flush(); } finally { rawOut.close(); }
} catch (FileNotFoundException exc) { ...do something not being able to create file...
} catch (IOException exc) { ...handle create file but borked - oops...
}
2

You Might Also Like