No method declares a foreign exception
Checked Exceptions can be a pain, best way to deal with (80% of the time, see for the remaining 20% the text below) them is


} catch (ProprietaryException pe) {
new MyException(pe);
}

The main reason is that otherwise ProprietaryException is leaked and that you have to support it until the end of the times. Even if you change your implementation, you’ll cary this exception in your distribution. It is obvious that you don’t want this. So if you really want to declare a checked exception, the exception should be declared in the same packages where your API is declared.
Exceptions are part of your interface. You should have a good reason to force the user to handle it. The hard part with exceptions is when you should use them.

The other 20%
The really annoying java.sql.SQLException is a good example. It is in its raw for absolutly useless. What is the point in catching an exception that a table doesn’t exist? An application can’t do anything about it, unless you have one of these apps that create the tables on their own (Note that in any large organization the DBA will come after you for something like that).
Anyway, this example shows that the requirements when a checked exception is appropiate differ, I use three categories

  1. Exceptions I cannot help
  2. Exceptions that I catch because I know about the internals
  3. Exceptions that form a second channel of information

Most RuntimeExceptions fall into category 1; normally I rethrow them, but in API-methods I may want to catch them as they might leak implementation details: User of the API sometimes use the debugger and may discover that they always get the same class as exception or that the causing exception is always the same. They use this to handle the exception that you used as a exception of the first kind as type 3 and might complicate the issue by “retrying” with different parameters. This is likely to enter a control-path in your system that is barely explored (=tested). So if you think you have an error where no real handling is possible, clean the exception before rethrowing. Cleaning should not mean to make it free of infomation, it must contain at least the info to form an error message.

The second kind is why you want to clean the outgoing exceptions. The SQLException might tell you that the password is wrong or the network is down. These exceptional situation are different: You have to ask the client to provide the proper credentials, so you transform the exception into an exception of the third kind, otherwise you might retry inside you code to shield the client from the detail that a network is involved.

The third kind is quite disputed. Some argue that exception complicate things as the form a second flow of control. Yes, that’s what they are for. And yes it can be hard. In general this is managable if the alternate flow is limited. The checked exception in most general purpose APIs don’t qualify for this: You cannot limit the scope of something that is generic and this led to code that is polluted with meaningless “throws” declaration and contributed to the bad image of exceptions.
An example: We have a remote service that takes a request object and gives us some response if everything went OK:

try {
rspObj = myRmtSvc.invoke(rqObj);
client.set(rspObj);
} catch ( RmtSvcException rme) {
client.handle(rme.getProblemList());
}

As an alternative we could have encoded the problem-list into the response, but this would defer either error detection to the user of the code (which is not reliable) or would make us to mangle errors into a container and unmangle it afterwards - here the checked exception provides us with a second channel that clearly separates the handling of a proper response from a failure. The key is that the RmtSvcException is contained in the code that deals with the interface and that the interface of the response object stays clean.
If the call above wouldn’t handle the exception - which can easily happen if it wasn’t checked - the exception might leak into other layers of the code with the problems mentioned above.

A common error with exception is that they are abused:

void myMethod() throws LargeData,DatabaseCorrupt,EverythingOK

Note that the “exceptions” don’t even carry the extension “Exception”. The abuse here is that a method had been created that ants to return three different types. This is not nice (the alternative was Object with instanceof test), but forcing the caller to use catch clauses to get the “return value” is ill.

A borderline case is

int getIntIfNumberOrZero(String str) {

try {

return Integer.parseInt(str);

} catch (NumberFormatException nfe) { return 0;}

}

The exception mechanism should in general not be used to replace simple decisions. Here it would be cleaner to check if the string would pass parseInt and to return parseInt or zero depending on the result. The exception mechanism has some perfomance impact and should be used wisely. This case is on the vorder as it is hard to verify a string this way, perhaps the penalty for the double ckeck is more expensive than the overhead caused by the exception.

This contradicts a bit the checked exception mechanism shown above, but this is the actual work when designing software. There are never recipes that work always, you always have to use good judgement to balance between usability and strictness.