Why would I care about IOExceptions when a file is closed? - java

I've see this sort of thing in Java code quite often...
try
{
fileStream.close();
}
catch (IOException ioe)
{
/* Ignore. We do not care. */
}
Is this reasonable, or cavalier?
When would I care that closing a file failed? What are the implications of ignoring this exception?

I would at the very least log the exception.
I've seen it happen occasionally, if the attempt to close the file fails due to it not being able to flush the data. If you just swallow the exception, then you've lost data without realizing it.
Ideally, you should probably swallow the exception if you're already in the context of another exception (i.e. you're in a finally block, but due to another exception rather than having completed the try block) but throw it if your operation is otherwise successful. Unfortunately that's somewhat ugly to sort out :(
But yes, you should at least log it.

You would care if the close() method flushes written content from a buffer to the filesystem, and that fails. e.g. if the file you're writing to is on a remote filesystem that has become unavailable.
Note that the above re. flushing applies to any output stream, not just files.

The most common close() problems are out-of-disk space or, as Brian mentioned, a remote stream that's gone poof.
NOTE:
You should really see something like (note: I haven't compile-checked this)
SomeKindOfStream stream = null;
Throwable pending = null;
try {
stream = ...;
// do stuff with stream
} catch (ThreadDeath t) {
// always re-throw thread death immediately
throw t;
} catch (Throwable t) {
// keep track of any exception - we don't want an exception on
// close() to hide the exceptions we care about!
pending = t;
} finally {
if (stream != null)
try {
stream.close();
} catch (IOException e) {
if (pending == null)
pending = e;
}
}
if (pending != null) {
// possibly log - might log in a caller
throw new SomeWrapperException(pending);
// where SomeWrapperException is unchecked or declared thrown
}
}
Why all this?
Keep in mind that Java can only track one "pending" exception at a time. If the body of the main try block throws an exception, and the close() in the finally throws an exception, the only thing you'll know about is the close().
The above structure does the following:
Keep track of any throwable thrown in the body of the try
In case that exception is thread death, rethrow it immediately!
When closing, if we don't have a pending exception, track the close exception; otherwise the previously-thrown exception should be kept track of. (You should probably try to log the close() error in this case)
At the end, if there is a pending exception, deal with it. I usually wrap it and rethrow it. Personally, I use an unchecked wrapper so I don't need to have all callers in the call chain declare throws.
To do the above, I usually use the template method pattern to create the exception management and then override a doWork() method that is the body of the try.

Related

What is a IOException, and how do I fix it?

What are IO Exceptions (java.io.IOException) and what causes them?
What methods/tools can be used to determine the cause so that you stop the exception from causing premature termination? What does this mean, and what can I do to fix this exception?
Java IOExceptions are Input/Output exceptions (I/O), and they occur whenever an input or output operation is failed or interpreted. For example, if you are trying to read in a file that does not exist, Java would throw an I/O exception.
When writing code that might throw an I/O exception, try writing the code in a try-catch block. You can read more about them here: https://docs.oracle.com/javase/tutorial/essential/exceptions/catch.html
Your catch block should look something like this:
try {
//do something
}catch(FileNotFoundException ex){
System.err.print("ERROR: File containing _______ information not found:\n");
ex.printStackTrace();
System.exit(1);
}
Here you go https://docs.oracle.com/javase/7/docs/api/java/io/IOException.html
IOException is thrown when an error occurred during an input-output operation. That can be reading/writing to a file, a stream (of any type), a network connection, connection with a queue, a database etc, pretty much anything that has to do with data transfer from your software to an external medium.
In order to fix it, you would want to see the stack trace of your exception or at least the message, to see exactly where the exception is thrown and why.
try {
methodThrowingIOException();
} catch (IOException e) {
System.out.println(e.getMessage()); //if you're using a logger, you can use that instead to print.
//e.printStackTrace(); //or print the full stack.
}
The error message that will be printed will likely show you what the issue is. If you add the error message here, I'll be able to give you more info on how to fix that specific IOException. Without that, no one can really give you a complete answer.
It is a very generic exception that a lot IO operation can cause. A best way is to read the Stack Trace. To continue the execution you can use the try-catch block to bypass the exception, but as you mention you should investigate into the cause.
To print the stack trace:
try {
// IO operation that could cause an exception
} catch (Exception ex) {
ex.printStackTrace();
}
IOException is usually a case in which the user inputs improper data into the program. This could be data types that the program can't handle or the name of a file that doesn't exist. When this happens, an exception (IOException) occurs telling the compiler that invalid input or invalid output has occurred.
Like others have said, you can use a try-catch statement to stop a premature termination.
try {
// Body of code
} catch (IOException e) {
e.printStackTrace();
}

How to catch exception thrown by close method in try-with-resource statement

I was reading about try-with-resource statement in Java which can be used to specify any number of resources.
try (Resource1 res1 = initialize_code; Resource1 res2 = initialize_code; ...)
{
statement;
}
Now when the try block exits (normally or abnormally throwing an exception) the close methods of all resource objects are invoked. But some close methods can throw exceptions. What will happen in that scenario if close itself throws exception?
But some close methods can throw exceptions.
Yes they can and you are right. Also the resources are closed in reverse order of their initialization.
What will happen if close method itself throws exception?
As you mentioned some close methods can also throw exceptions. If that happens when try block is executed normally then the exception is thrown to caller.
But what when another exception had been thrown, causing close
methods of the resources to be called, and one of the close method throws an exception (exception of lower importance actually)?
In this situation original exception gets rethrown and the exceptions caused by close method
are also caught and attached as supressed exception. This is actually one of the advantge using try-with-resource becuase implementing such mechanism would be tedious to implement by hand.
try {
///statements.
} catch (IOException e) {
Throwable[] supressedExceptions = ex.getSupressed();
}

Handling different exceptions of the same type in Java?

When handling errors in Java it's common to see the superclasses being the errors that are caugh, such as
Exception, IOException, SocketException, etc.
However how do you go about finding the nitty-gritty details on the exception? How do you single a certain exception type out from the others. For instance, I'm currently working on a small project using Netty.io which throws an IOException for every type of read/write error you can name. This makes sense, because ultimately this is input/output errors, but how would I handle them individually.
Example exceptions:
java.io.IOException: An existing connection was forcibly closed by the remote host
java.io.IOException: Connection reset by peer
java.io.IOException: Stream closed
The list just continues to go on, but how would you go about handling these seperately, one approach that I've found while looking around and seems really nasty is the following.
try {
// ...
} catch (IOException e) {
if(e.getMessage().contains("An existing connection was forcibly closed by the remote host")) {
// Handle error
} else //...
}
This seems very tedious and there's bound to be a better way to do this, a correct way if you will. I've looked through quite a bit of error handling writeups over the last few hours and they all only talk about the big boys that are used commonly. IOException, Exception, SocketException, NullPointerException, and FileNotFoundException. Where I believe SocketException and FileNotFoundException would be directly related to the IOException, more than likely a subclass, correct me if I'm wrong.
Anyway, what's the proper way to go about handling these exceptions and how do you figure out exactly what kind of exception you need to be handling? All I can really do is handle IOException until something more precise comes up, but when developing applications it's always good to be able to handle each error uniquely.
In most of these cases the message is irrelevant from the point of view of your code. It's just something to be shown to the user, or logged. The only salient fact is that the connection is broken, for whatever reason, and there aren't different code paths you can use depending on which message it was.
The only one that's different is 'socket closed', which indicates a coding bug.
EDIT Regarding your comments below:
Any IOException other than SocketTimeoutException on a socket is fatal to the connection.
Invalid packets don't cause IOException: that's an application-layer problem that throws application-layer exceptions, or subclasses of IOException: e.g., java.io.StreamCorruptedException.
There is no such thing as IOException: connection closed by remote host. If the peer closes the connection, that causes an end-of-stream condition, which manifests itself as either read() returning -1, readLine() returning null, or readXXX() throwing EOFException for any other X.
I would suggest catching the exceptions in order, from most specific to least - such that you will notice a circuit break pattern when the exception you are looking for is reached. This is the best I can come up with:
try {
/// Something that can result in IOException or a SocketException
catch (IOException e){
//Do something specific
}catch (SocketExcpetion e){
}catch (Exception e) { //or some superclass of the above exceptions
///
}
Don't forget that you can also catch multiple exceptions of different types using the | command: catch (IOException|SocketException|
The documentation (http://docs.oracle.com/javase/7/docs/api/java/io/IOException.html) contains a long list of direct subclasses. You might want to look through them and check which ones you want to treat differently.
Once you know that, you can use multiple catch-blocks, first the subclasses, then the most general IOException:
catch(SSLException se) {
// do something
}
catch(HttpRetryException he) {
// do something else
}
catch(IOException ioe) {
// nop
}

Bluetooth InputStream.read() doesn't return Data and Blocks forever

I've got some problems with Android Bluetooth stuff.
When I call
bytes = mmInStream.read(buffer);
It usually works as it should.
On the Cat B15 smartphone however, the read method sometimes blocks forever, even though the connection is still running and data should be arriving.
I have temporarily solved the problem by this code:
while (true) {
int available = 0;
try {
available = mInStream.available();
} catch (IOException e) {}
if (available > 0) {
try {
bytes = mInStream.read(buffer);
ioExceptionsCounter = 0;
// [send the obtained bytes to the UI activity]
// ...............
} catch (IOException e) {
++ioExceptionsCounter;
if (ioExceptionsCounter >= 4) {
break;
}
}
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {}
}
I dont think that the ioExceptionsCounter is really necessary but there was some complaints that it sometimes disconnects without reason so I thought one IOException might not be enough to close the connection.
What I really don't like about this is that it uses polling. It does work now on the Cat phone but it doesn't make me happy that all the other devices now execute this ugly code.
Do you have any ideas why this could be? Is this just a bug of the phone? By the way it runs ICS but it is definitely device specific.
I'm inclined to think that you are encountering a hardware-specific bug.
The various InputStream.read() methods are documented to block until at least one byte is read, or the end of the stream is detected, or an error occurs. If the read() sometimes blocks forever for you in the event that no bytes are available when it is first invoked, then that's definitely a bug outside your own code.
Also, it's highly questionable to ignore any number of IOExceptions, either from available() or from read(). After the stream throws an exception you cannot be confident of the integrity of anything you afterward might manage to read from it. I would normally expect such attempts at further reading also to throw IOExceptions. If you are getting spurious IOExceptions on the Cat B15, such that simply retrying your read() successfully obtains the correct data, then that is also a bug (maybe another facet of the same one).

java: log exception being thrown

In java, I want to log the exception being thrown from a piece of code:
try
{
doRiskyThing();
}
catch(Throwable t)
{
log.warn("too bad");
throw t;
}
The problem is that now my method must declare it throws throwable.
On the other hand, if I log the exception in a finally block, how do I know what exception is being thrown (and if any exception is being thrown at all).
You could at least write a catch for unchecked and n catch blocks for checked exceptions.
try{
..
}catch(RuntimeException e){
log(e);
throw e;
}catch(ExceptionException ..){
log(e);
throw e;
}
This will not change the signature of your method. Catching Errors is a bit of a smell. Well, logging and throwing exception is a smell, too. This will duplicate error messages.
Advance exception handling is a feature that was removed from project coin in JDK 7.
This seems to be the wrong place to log the exception. Either log it within doRiskyThing() when throwing it, or log it where it is supposed to be captured.
This should work:
try
{
doRiskyThing();
}
catch(RuntimeException e)
{
log.warn("too bad");
throw e;
}
catch(Exception e)
{
log.warn("too bad");
throw new RuntimeException(e);
}
catch(Error e)
{
log.warn("too bad");
throw e;
}
But it's ugly and I'd rather have a single catch block that catches everything and logs it at the top level of the app, with no re-throwing. The stack trace lets you pinpoint the problem anyway.
Catching Throwable in itself is already bad practice (and flagged as such by many code quality checking tools). Wrapping it in a RuntimeException and rethrowing it? Terrible! The whole point of having an exception hierarchy is undermined by this.
The 'trend' away from checked exceptions is actually a bit more subtle. Between architectural layers (or for example at a framework API boundary) it is common practice to define one or more meaningful exception types and wrap any implementation-specific errors in them (take a look at Spring or Hibernate for example).
Making exceptions checked or not is a matter of style. If there is a good chance that the caller will be willing and able to handle the error condition then I make it checked (e.g. concurrent update detected), otherwise unchecked (e.g. database connection error). Unchecked exceptions should 'bubble' up through your application code (i.e. not be caught) and handled at a high level by displaying some sort of error page/screen.
You can log the Throwable, and throw a RuntimeException.
In Java, you have to declare any exception that your method might itself throw, because it's considered part of the method's signature.... that is, apart from RuntimeException, which avoids that rule. The RuntimeException can give the message of the Throwable as part of its message, if you like.
try
{
doRiskyThing();
}
catch(Throwable t)
{
log.warn("too bad, exception thrown: " + t.getMessage());
throw new RuntimeException("Throwable exception was thrown, message: " + t.getMessage());
}
Beware however that this may be considered bad practice, and for more long-term code it's recommended that you throw a non-runtime exception and define it in the method's signature.

Categories

Resources