How do you know all the exceptions a method can throw - java

Is there a way to get some details regarding exception safety aspects of Java's standard classes? Mainly working with C++ and C#, I'm confused with Java exception specifications, so I need to understand the proper way of working with exceptions.
To be more specific, let's consider ServerSocket. It starts listening for incoming connections as soon as its object is constructed. Then, you should use accept() to accept the connection (if someone tries to connect).
In case you've previously configured your server socket with setSoTimeout(), there's a change that accept() will throw SocketTimeoutException because nobody tried to connect in a specified period of time. That's fine, server socket is still usable, so you just call accept() once again.
But SocketTimeoutException is not the only thing that accept() may throw. What does all the other exceptions mean? If I wrap call to accept() with 2 catch clauses: for SocketTimeoutException and IOException, can I still safely use the related ServerSocket instance after I got into IOException clause?
I'd really appreciate both Java-wide and ServerSocket-specific answers.

It is not safe to reuse the object. For such a question I would always look into a source, that is the reason it is open.
So if you look into that one: http://kickjava.com/src/java/net/ServerSocket.java.htm you notice that in accept() a SocketException (inherits from IOException) is thrown if the socket is closed or not bound anymore. Both states indicate that the ServerSocket is not valid anymore.
So for this class, generally, if you fail with an exception, always try to gracefully close the ServerSocket in a finally block and then recreate it.
Additionally on your Java-wide question scope: Always look into the source and understand what the interface is doing. If it is mission-critical write tests that reproduce the behaviour (should not be easy at all with such a low-level api).
Finally - is Java consistently doing such things that way? No. Some classes are stateless, others are not (like ServerSocket), some are thread-safe, others not. And you need to understand - either from the documentation or (mostly) from the code - what state they build in order to understand what to do when an Exception knocks you off from the main path.
Most people curse those checked Java exceptions, because most of them (as with most of the IOExceptions) are not really recoverable in a meaningful way. Most of the time, they argue, you cannot understand each and every fine corner case. Which is the reason why many complex frameworks may retry twice or thrice if they think in this case they might, but finally throw a RuntimeException to a top framework layer. There they make something useful out of it (a meaningful error providing context) and log all the details they have, which is a huge stack trace most of the time. A great resource of knowledge, feared by many developers.
So what can you do if you could not recover from an untested corner-case problem? Throw up (probably with a some subclass of RuntimeException) the most meaningful stacktrace annotated with all the context you have. Setup monitoring. And if you run into a frequent problem, fix it.

Yes. The object still exists - May be in an error state in which case it will throw other exceptions until that is rectified.

If you read the specification for ServerSocket, you will see that it throws an IOException "if an I/O error occurs when waiting for a connection." Is it safe to accept() on the socket again? Yes. Are you going to get the same Exception thrown again? Likely so.

I have not yet found an easy way to see if an object is still in a usable state. Each object makes its own rules.
In your specific case with ServerSocket I would try one of two different things:
Run netstat or some other utility to see what the OS thinks that the socket is doing. If the OS doesn't think it is listening, then something happened.
or
Write a test program that will throw the exception and see what it does. I do this all the time (especially with proprietary software). It would be harder in the ServerSocket case you picked, since all of the scenarios I can think of (e.g. address in use, insufficient privileges, etc.) would never result in an object being still valid.

But SocketTimeoutException is not the only thing that accept() may throw. What does all the other exceptions mean?
According to the javadoc, the declared exceptions are IOException, SecurityException, SocketTimeoutException and IllegalBlockingModeException. The SecurityException and IllegalBlockingModeException only occur in specific contexts and you should not attempt to catch and handle them. (They are not problems you want to try to recover from!) The IOException case occurs when "some other I/O error" occurs. The javadoc does not specify what those I/O errors might be, but possibilities might include such things as:
the address to which you have bound is no longer valid
a transport protocol error has occurred
some error (resource issue, bug ...) occurred in the OS protocol stack
(The fact that the javadoc doesn't say which IOException subclasses might be thrown is a hint that you shouldn't try to do clever things to try to recover. If you do, your code is likely to be platform dependent.)
If I wrap call to accept() with 2 catch clauses: for SocketTimeoutException and IOException, can I still safely use the related ServerSocket instance after I got into IOException clause?
Yes and no. It is safe in the sense that you won't put your application into a worse state than it is already in. On the other hand, there is no guarantee that the next accept call won't fail with the same problem.
If your application is intended to run as an unattended server, I don't think you have much choice but to log the IOException and try again ... hoping that the problem is transient.

You can find your answer to the javadoc of setsoTimeout, it says :
Enable/disable SO_TIMEOUT with the specified timeout, in milliseconds. With this option set to a non-zero timeout, a call to accept() for this ServerSocket will block for only this amount of time. If the timeout expires, a java.net.SocketTimeoutException is raised, though the ServerSocket is still valid. The option must be enabled prior to entering the blocking operation to have effect. The timeout must be > 0. A timeout of zero is interpreted as an infinite timeout.

Related

Socket Exception - How to get original socket from Socket Exception object

I have one method that transfers data from one socket to another. Now whenever there is some problem either on any socket I need to detect which socket has caused Socket Exception. Is this possible to detect it from Socket Exception object ?
Not from the exception itself, but you can from the context. If the code manipulates only one socket, clearly the exception must relate to that socket.
It sounds like you are not handling your exceptions at an appropriate level, instead handling (catching) a low level exception at a high level part of your program, and expecting to be able to do low level handling at that point.
Consider catching the exception at an intermediate level, partially handling it, then rethrowing it. You might want to do exception translation (chaining) at that point.
You can't get it from the excpetion, because ther is no property where the socket is saved.
Simple answer is 'NO'. Since Exceptions in Java are made to notify an unexpected behavior, they are not made to store any reference to the object in error. You can see in this exception class or any of it's supertypes. None of them is able to hold reference to any object.

Why is InputStream.close() declared to throw IOException?

The java.io.InputStream.close() method is declared to throw an IOException. Under what circumstances would such an exception actually be thrown?
Edit: Yes I have read the javadoc. Can anybody be more specific than "when an I/O error occurs"? What I/O error can occur while closing an InputStream?
In the case of input stream reading from a file system, an error can be raised while the file system itself updates the last access time metadata, or some other metadata, on a file during closure. Anyway, this happens almost never in practice.
In the case of an input stream reading from a network connection, an error on closure is a bit more conceivable. A normal closure of a network socket actually involves a closure request (TCP/IP FIN packet) being sent over the connection and waiting for the other end to acknowledge this closure request. (In fact, the other end of the connection then in turn sends a closure request, which the closing end acknowledges.) So in the case of a socket input stream, a closure operation actually involves sending traffic over the connection and the closure can thus fail with an error.
Note that in many implementations, close() generally doesn't throw an IOException if the stream is already closed; it simply fails silently to close the stream again.
I'm looking through the Java source code, and have found something interesting which is indicative of the IOException reason. InputStream is an abstract class. We therefore can't predict the kind of input which will be closed, so it's good to keep information flowing.
Whatever code uses that input stream needs to be able to throw an IOException, because there is a chance that closing the input stream may fail. If it fails, whatever's using the implementation needs to know about it, because there's a good chance it needs to be handled.
It's important to understand the layout of the Exception structure in Java. Every exception, of course, extends Exception. However, there are also broader categories of exceptions: java.lang.IOException is one of these, and covers all possible input/output exceptions. When we say there has been an I/O error, we're referencing anything which falls under IOException. As a result, many exceptions extends this one, e.g. FileNotFoundException, EOFException, etc. as it's important to have a broad, overarching exception to manage these.
As a result, any IO class will need to be able to throw any of the various IOExceptions on close. close() therefore must throw IOException - this gives its implementation the ability to throw any of the extensions of IOException as well. This is why close() throws IOException - exceptions are inherited, and you need to be able to any of the IOExceptions when closing a stream.
Here are a couple scenarios worth noting:
You can't close an IOStream twice, though this generally doesn't throw an exception if you do
The content becomes inaccessible (e.g. a disk was unmounted) (The close() is actually critical for the operating system, as it needs to have an indicator of when the file is no longer busy)
The generic source has closed
Any generic failure not covered by all other subclasses of IOException (e.g. FileNotFoundException)
You can check what caused an IOException by running Exception.getMessage().
The underlying close system call will have to be made eventually, e.g. on linux http://linux.die.net/man/2/close. That call is documented to fail with EIO: "An I/O error occurred." So the reason is, that the underlying file system close call can fail.
I have wondered about this myself and have done a little research on this topic few years ago. This is what I know....
If you look at the javadoc in the link you provided, it clearly states that "The close method of InputStream does nothing", so there is no way it would throw an exception, correct? But then looking at all of the subclasses of IOException you will see that there are many situations where subclasses of inputstream may not be able to close the stream. So my best guess is that this exception is designed for subclasses to make use of it.
http://docs.oracle.com/javase/6/docs/api/java/io/IOException.html
In some cases, it is nothing more than a nuisance, and in others it clearly indicates that something went wrong. It all depends on what type of inputstream implementation you are making use of.

Why do IOExceptions occur in ReadableByteChannel.read()

The specification of ReadableByteChannel.read() shows -1 as result value for end-of-stream. Moreover it specifies ClosedByInterruptExceptionas possible result if the thread is interrupted.
Now I thought that would be all - and it is most of the time. However, now and then I get the following:
java.io.IOException: Eine vorhandene Verbindung wurde vom Remotehost geschlossen
at sun.nio.ch.SocketDispatcher.read0(Native Method)
at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:25)
at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:233)
at sun.nio.ch.IOUtil.read(IOUtil.java:206)
at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:236)
at ...
I do not unterstand why I don't get -1 in this case. Also this is not a clean exception, as I cannot catch it without catching any possible IOException.
So here are my questions:
Why is this exception thrown in the first place?
Is it safe to assume that ANY exception thrown by read are about the socket being closed?
Is all this the same for write()?
And by the way: If I call SocketChannel.close() do I have to call SocketChannel.socket().close() as well or is this implied by the earlier?
Thanks, Steffen
Funny, but somebody today already posted a link to Fallacies of Distributed Computing.
In your case, as a fine German to English translator tells me An existing connection was forcibly closed by remote host.
When you deal with I/O, and specifically Socket I/O, you have to be prepared that any IOException would be thrown at you.
Some of them, like ClosedByInterruptException you may handle intelligently. Others, you may
Add throws declarations to you method and let callers deal with IOExceptions
Wrap IOExceptions into checked exception specific to your subsystem
Wrap IOExceptions into RuntimeException specific or not to your subsystem
Log IOException and continue.
In any case, once you get IOException, you probably cannot do much to communicate with that channel. So you may just close your connection and retry later.
BTW, read will only return -1 to you if you SUCCESSFULLY reached end-of-stream. In your case, I am sure, the connection is closed midstream.
EDIT in reply to OP comments
Can I prevent a channel to be
interruptible?
No, this is a property of specific channel that you are using. If it implements InterruptibleChannel, then it IS interruptible, and will be closed upon receipt of thread interrupt. java.nio.channels.SocketChannel is interruptible
The docs for
ClosedByInterruptException state:
"Checked exception received by a
thread when another thread interrupts
it while it is blocked in an I/O
operation upon a channel." Still how
can it be blocking, if it is
NON-blocking IO?
If you look at specification of ReadableByteChannel.read you will see that the method is declared to only throw IOException. Then in JavaDoc it hints what kind of specific IOExceptions and undre what conditions may be thrown by a standard java.nio implementation of this interface. This is one of the example of cooperative programming. The declarer of the interface tells the implementer how they should implement the method and what exceptions should they throw under what conditions.
For example, if I implement the read method in my exotic channel I may choose to totally ignore the specification and not throw any of exception in the declaration. The user of my class though will probably pay a heavy price when encountering unexpected behavior and will probably dump my implementation in favor of more robust one.
In any case, I think you are confused with how you should react to different exceptions declared in read method.
First of all, not every exception in read method specification may be thrown. Case in point ClodesByInterruptException most likely will NOT get thrown in case you are using a NON-blocking I/O. On the other hand some implementers may choose to close the channel upon receipt of the interrupt and throw this exception when you attempt to read even if you are in NON-blocking I/O. But you really should not get concerned with that decision, because:
You probably control whether current
thread is interrupted or not
This is just the other kind of
IOException, and by default should
be treated as fatal
And yes, the example IOEception is
fatal, but my question is: Are they
ALL?
Remember, that your framework should function normally, or shutdown gracefully when any kind of exception is thrown. For example your code, or library code at any point can throw unchecked ( Runtime ) exception. Only testing and more intimate knowledge of your environment can tell you which exceptions are truly fatal and which can be handled safely.
Because frameworks are written by people they also have bugs, deficiencies, etc. So there may be a case when IOException is thrown, but the underlying channel is still OK. Unfortunately these conditions can only be found with blood and guts in real production environment. Here is one of the example where IOException thrown by a socket can be totally ignored: http://bugs.sun.com/view_bug.do?bug_id=4516760.
So, start by writing generic handler for all IOExceptions and treat them all as fatal, relax it for specific conditions that you find out in production.
Per the documentation here:
Checked exception received by a thread
when another thread interrupts it
while it is blocked in an I/O
operation upon a channel. Before this
exception is thrown the channel will
have been closed and the interrupt
status of the previously-blocked
thread will have been set.
This suggests that the thread that owns the ReadableByteChannel is being interrupted by another thread in your application... is this the case?
If another thread was closing the channel, I would expect you would see a AsynchronousCloseException.
I don't see a reason why you couldn't catch the ClosedByInterruptException explicitly and allow any other exceptions to be handled higher up the stack:
try
{
rbc.read(dst);
}
catch ( ClosedByInterruptException cbie)
{
/* handler */
}
As for write(), there is no write() method for ReadableByteChannel, however, the WritableByteChannel, does have a write() method and it can throw the same exceptions.

When is it OK to catch a RuntimeException

On a recent project I recommended catching a RuntimeException within a test harness code and logging it. The code processes a series of inputs from a database, and I do not want the test to stop due to failure of any one input (Null values, Illegal arguments, etc.). Needless to say, my suggestion triggered a passionate discussion.
Is catching any kind of RuntimeException acceptable? If yes, what are other scenarios where it is OK to catch RuntimeExceptions?
You catch RuntimeException for the same reason that you catch any exception: You plan to do something with it. Perhaps you can correct whatever caused the exception. Perhaps you simply want to re-throw with a different exception type.
Catching and ignoring any exception, however, is extremely bad practice.
Unless you can correct a RuntimeException, you don't want to catch it...
...only true from a developers point of view....
you have to catch all exceptions before they reach up to the UI and make your user sad. This means on the "highest level" you want to catch anything that happend further down. Then you can let the user know there was a problem and at the same time take measures to inform the developers, like sending out alarm mails or whatever...
It is basically considered a data/programming error that could not be forseen, thus you want to improve future releases of the software while at the same time take the user by the hand and move on in a controlled manner...
RuntimeException is intended to be used for programmer errors. As such it should never be caught. There are a few cases where it should be:
you are calling code that comes from a 3rd party where you do not have control over when they throw exception. I would argue that you should do this on a case by case basis and wrap the usage of the 3rd party code within your own classes so you can pass back non-runtime exceptions.
your program cannot crash and leave a stack trace for the user to see. In this case it should go around main and around any threads and event handling code. The program should probably exit when such exception occurs as well.
In your specific case I would have to question why you are having RuntimeExceptions occur in the tests - you should be fixing them instead of working around them.
So you should guarantee that your code only throws RuntimeExceptions when you want to have the program exit. You should only catch RuntimeExceptions when you want to log it and exit. That is what is in line with the intent of RuntimeExceptions.
You can look at this discussion for some other reasons that people give... I personally haven't found a compelling reason in the answers though.
In my code 99% of my exceptions are derived from runtime_exception.
The reasons I catch exceptions are:
Catch Log and Fix problem.
Catch Log and Generate a more specific exception and throw
Catch Log and rethrow.
Catch Log and Kill operation (discard exception)
User/request initiated action fails.
An HTTP request handler for example. I would rather the requested operation die rather than bring the Service down. (Though preferably the handler has enough sense to return a 500 error code.)
Test case passed/failed with an exception.
All exceptions not in the main thread.
Allowing exceptions to escape a thread is usually badly documented but usually causes program termination (without stack unwinding).
Years ago, we wrote a control system framework and the Agent objects caught runtime exceptions, logged them if they could and continued.
Yes we caught Runtime exceptions including OutOfMemory in our framework code( and forced a GC, and it's surprising how well that kept even quite leaky code running.)
We had code that was doing very mathematical things involving the real world; and from time to time a Not-A-Number would get in due to tiny rounding errors and it coped okay with that too.
So in framework / "must not exit" code I think it can be justifiable. And when it works it's pretty cool.
The code was pretty solid, but it ran hardware, and hardware tends to give screwy answers sometimes.
It was designed to run without human intervention for months at a time.
It worked extremely well in our tests.
As part of the error recovery code, it could resort to rebooting the entire building using the UPS's ability to turn off in N minutes and turn on in M minutes.
Sometimes hardware faults need to power cycled :)
If I remember, the last resort after an unsuccessful power cycle was it sending an email to it's owners, saying
"I tried to fix myself and I can't; the problem is in subsystem XYZ", and included a link to raise a support call back to us.
Sadly the project got canned before it could become self aware :)>
Personally, I've always been told that you want to catch all RuntimeExceptions; however, you also want to do something about the exception, such as running a failsafe or possibly just informing the user that an error occurred.
The last Java project that I worked on had a similar approach, at the very least, we would log the exception so that if a user called complaining about a bug, we could find out exactly what happened and see where the error occurred.
Edit 1: As kdgregory said, catching and ignoring are two different things, generally, people are opposed to the latter :-)
We all know that checked exceptions and RuntimeExceptions are the two categories of exceptions. It is always suggested that we handle (either try-catch or throw) the checked exceptions because they are the programming conditions where unfortunately programmer can not to do anything on its own;
Like FileNotFoundException it is not the programmer who puts files on user's drive if program is actually trying to read the file 1.txt which is supposed to be there on f:\ of user with the statements:
File f11 = new File("f:\\1.txt");
FileInputStream fos = new FileInputStream(f11);
If the file is found it's all ok, but what happens in the other case if the file is not found is that, program crashes down with 0 error from the user. In this scenario programmer did not do anything wrong. This could be a checked exception which must be caught for the program to continue running.
Let me also explain the second scenario with which the concept of RuntimeException will be clear. Consider following code:
int a = {1,2,3,4,5};
System.out.println(a[9]);
This is poor coding which generates the ArrayIndexOutOfBoundsException. Which is an example of RuntimeException. So programmer should not actually handle the exception, let it crash the program, and later fix the logic.
You catch RuntimeException when you want to process it. Maybe you want to rethrow it as a different exception or log it to a file or database, or you want to turn on some exception flag in the return type, etc.
You catch RuntimeExceptions (in any language: unexpected exceptions/“all” exceptions) when your program is doing multiple subtasks and it makes sense to complete every one you can rather than stopping on the first unexpected situation. A test suite is a fine situation to do this — you want to know which of all the tests failed, not just the first test. The key characteristic is that each test is independent of all the others — it doesn't matter whether a previous test doesn't run because the order is not significant anyway.
Another common situation is a server; you don’t want to shut down just because one request was malformed in a way you didn't expect. (Unless it’s really, really important to minimize the chances of inconsistent state.)
In any of these situations, the appropriate thing to do is log/report the exception and continue with the remaining tasks.
One could vaguely generalize to any exception: it is “appropriate to catch” an exception if and only if there is something sensible to do after catching it: how your program should continue.
If a client can reasonably be expected to recover from an exception, make it a checked exception.
If a client cannot do anything to recover from the exception, make it an unchecked exception.
Here's the bottom line guideline.
From Java Docs. Please read this Unchecked Exceptions — The Controversy

Why does Java have both checked and unchecked exceptions? [duplicate]

This question already has answers here:
Closed 13 years ago.
Possible Duplicate:
When to choose checked and unchecked exceptions
Why does Java as a language have both checked and unchecked exceptions. What purpose do they serve?
Note: I'm not asking when I should use them, or how to code them, but what they add to the language.
The theory for checked exceptions is simple.
When designing an interface, think of exceptional cases that can occur, and will occur, with the normal state of a method call. Declare these exceptions in your interface, as the programmer will have to handle them directly.
For example, a bank account withdraw method may declare an OverdraftException, which is an expected exception - a withdrawal may fail due to overdraft, but this type of failure may be handled differently by the client code (one may decide to completely deny the withdrawal, another may decide to apply a huge penalty and allow for a negative balance to be recorded, another may decide that their client is allowed to draw from a different account).
However, runtime exceptions were supposed to be programming errors that weren't supposed to be handled directly - such as NullPointerExceptions, which only occur if methods take invalid arguments or don't check for such cases directly.
This is a good theory. However, Java messed up with its implementation of Exceptions, and this threw the book of this theory out the window.
There are two cases that I will illustrate where Java messed up with its implementation of Exceptions. These are IOException and SQLException.
An IOException occurs anytime, anywhere a stream in the IO libraries of Java messes up. This is a checked exception, however. But, generally you cannot do anything but log that an error occur - if you're simply writing to the console, what can you reasonably be expected to do if you suddenly get an IOException when you're writing to it?
But there's more.
IOException also hides stuff like file exceptions and network exceptions. They may be subclasses of IOException floating around for that, but it is still a checked exception. If your writing to an external file fails, you can't really do much about it - if your network connection is severed, ditto.
SQLException is the same way. Exception names should show what happened when they are called. SQLException does not. SQLException is thrown any single time any possible number of errors are encountered when dealing with a database - MOST OF WHICH THAT HAVE NOTHING TO DO WITH SQL.
Therefore, programmers typically get annoyed with handling exceptions, and let Eclipse (or whatever IDE they're using) generate blocks like this:
try {
thisMethodThrowsACheckedExceptionButIDontCare();
}
catch(Exception e) {
e.printStackTrace();
}
However, with RuntimeExceptions, these intentionally bubble up and eventually get handled by the JVM or container level. This is a good thing - it forces errors to show up and then you must fix the code directly instead of ignoring the exception - you may still end up just printing the stack trace (hopefully logging it instead of printing to the console directly), but then there will be an exception handler that you were forced to write because of a real problem - not because a method said that it might possibly throw an Exception, but that it did.
Spring uses a DataAccessException to wrap SQLExceptions so that you don't have to handle them as a checked exception. It makes code much cleaner as a result - if you expect a DataAccessException, you can handle it - but most of the time you let it propagate and be logged as an error, because your SQL should be debugged by the time you release your application, meaning the DataAccessException is probably a hardware issue that you could not resolve - DataAccessException is a much more meaningful name than SQLException, because it shows that access to data failed - not that your SQL query was nessecarily at fault.
They add a differentiation between errors that the designer of a library feels must be caught, and ones that they feel the programmer shouldn't handle.
For example it might be reasonable for a program to handle bad input from a user, but if something goes wrong with the underlying OS and threads starts to die without reason, it isn't something that the program should be expected to handle.
Personally, I think checked exceptions were a mistake in Java.
That aside, designating both checked and unchecked exceptions allows a library to differentiate between recoverable and unrecoverable errors. By making all recoverable errors throw checked exceptions, a library/language can force a developer to handle the edge cases they might otherwise paper over.
The big problem with this:
try{
myCode();
}catch(Exception e){ //Do nothing }
Additionally, in most cases it really is best to just throw up your hands and pass an exception up when one occurs. By forcing checked exceptions to be declared, a method that really doesn't care if an error occurs ends up having dependencies (in terms of compatibility, but also code-smell and others) it really shouldn't.
I think Sun initially thought it would be a good idea because the programmer is forced to handle the exception. However, many years later, pretty much everyone agrees they are a bad, unneccessary addition.
One of the main issues (apart from cluttering code) is that they leak abstractions form lower layers to higher layers (such as rmi remote exceptions)
Checked and unchecked exceptions invokes a bit of a religious argument - Java fell one side of the fence, C# the other.
In Java checked exceptions should be used when the calling code can recover from the error as where unchecked exceptions are used when there's a critical error (with perhaps the exception - no pun intended - of NullPointerException) that the calling code is unlikely to be able to recover from.
Personally I like to have both available to me generally favouring checked exceptions because they allow me to force the calling code to deal with an error situation that a developer might otherwise have ignored (although the infamous empty catch block side-steps this).
I don't think there's anything at all conceptually wrong with checked exceptions... but they do tend to suck mightilly in practice, because (especially early) library developers over-use them.
Also the "catch or declare" requirement does NOT fit well with interfaces.
My basics thoughts are: "Stuff that goes wrong" comes in two basic flavours: recoverable, and unrecoverable... Ergo: Business Exceptions and System Errors.
For instance: What do you (the library developer) expect me (the application programmer) to do about recovering from a failure in a call to SomeStream.close()? Yes, I definately need to be made aware that something has gone horribly wrong, but really my only option is to terminate the program/request/process/thread which tripped over it. I cannot be reasonably expected to even attempt to recover from the situation... Ergo: It's an uncoverable error, and therefore I shouldn't be forced to write a lot of highly repitious boilerplate catch-blocks which don't handle the problem at every level of the (potentially very deep) callstack. Therefore I believe it would be better if "catch all" checked exceptions such as IOException had never been invented... CloseException extends UncheckedIOException would be more appropriate, IMHO.
Also, if I had a time machine I'd go back in time and plead with the Java gods for:
interface Throwable
abstract class Exception
abstract class CheckedException
abstract class UncheckedException
class Error
Also: I'd love to see a #FaultBarrier class-annotation, which makes the compiler enforce: All exceptions (especially unchecked ones) must be caught or explicitly thrown. The most horribilest hunk of system I've ever worked on was riddled with throwings of raw RuntimeException; It's enough to make you weep.
Cheers. Keith.

Categories