13

Started learning java a week ago and also decided learning the right way to work with exceptions. Java really drives me mad with the idea of specifying exceptions the method can throw as part of its signature.

I'm currently trying to implement multi-threaded server for client-server application. I was very surprised with the fact socket.close() can throw IOException. The question is, what do I do if it happens?

...
final Socket socket = .... // at this point I know that I have a good socket
try {
  ..... // communicating with someone on that side....
} catch(IOException e) {
  // communication failed
  // this fact is useful, I can log it
  // and will just hang up
} finally {
  try {
    socket.close(); // bye-bye
  } catch(IOException e) {
    // anything but logging I can do here?
  }
}
...

This piece of code is executed within a separate thread, so I just have to catch all the exceptions. The problem is mostly psychological - I know, I can just leave catch block empty, but I'm trying to avoid this trick.

Any thoughts?

Andrey Agibalov
  • 7,624
  • 8
  • 66
  • 111
  • 3
    There isn't a whole lot you can do there. The recent Java 7 release has a `try-with-resources` block, that will automatically close any resources you specify in the try block, which will take care of this issue forever hopefully. There is a good example on this blog: http://www.baptiste-wicht.com/2010/08/java-7-try-with-resources-statement/ – Hunter McMillen Aug 10 '11 at 13:37
  • Curious about the semantics. `FileInputStream.close()` throws - what does it look like in this case? – Andrey Agibalov Aug 10 '11 at 13:39
  • 2
    Newsflash: [Java 7 is no longer upcoming](http://www.oracle.com/technetwork/java/javase/jdk7-relnotes-418459.html) ;-) – Joachim Sauer Aug 10 '11 at 13:39
  • @Joachim, you are correct. For some reason I thought it was the end of August not July – Hunter McMillen Aug 10 '11 at 13:41
  • 1
    [Who cares?](http://stackoverflow.com/questions/184618/what-is-the-best-comment-in-source-code-you-have-ever-encountered/184682#184682) – Coeffect Aug 10 '11 at 13:42

6 Answers6

13

It's quite common that you don't do anything major when closing a resource fails. Logging is probably a good idea, so that you have a chance to find out if it happens more often.

This is different if closing the resource is also the "commit" or in some other way persists the change: then you'd need to treat it just like you would treat an exception in any other part: handle it.

Note that Java 7 has introduced automatic resource management specifically to simplify these kinds of constructs. And if you learn Java now, then I'd suggest going with the latest-and-greatest.

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
3

I guess it depends if you read data from the socket or wrote data to it. If you read data and retrieved all the info you wanted then you can safely ignore the exception. But if you wrote data you probably have to assume that it did not get transmitted correctly.

devconsole
  • 7,875
  • 1
  • 34
  • 42
3

Apache Commons IO (a library that I can't hardly write Java without) has a method IOUtils.closeQuietly() for just this purpose.

So you can do:

final Socket socket = .... // at this point I know that I have a good socket
try {
  ..... // communicating with someone on that side....
} catch(IOException e) {
  // communication failed
  // this fact is useful, I can log it
  // and will just hang up
} finally {
  IOUtils.closeQuietly(socket);
}

and save yourself 5 lines of code.

As a bonus, closeQuietly() does the right thing if the socket is null or already closed. And there are overloads for anything else Closeable as well.

Daniel Pryden
  • 59,486
  • 16
  • 97
  • 135
  • 1
    *socket is null or already closed*, if you have a null socket, you do have a bug in the code, logic. (`final socket` = should not result in null but an exception) – bestsss Aug 16 '11 at 09:43
  • @bestsss: Indeed, that would never happen in the given code sample. The point I was trying to make was that `IOUtils.closeQuietly()` is a handy utility function that can be used in other circumstances as well. – Daniel Pryden Aug 16 '11 at 15:43
1

As said in the comments, there's not much you can do there. I suggest you log an error anyway, this way if it ever does happen, you at least have a place to start looking.

Jeremy
  • 22,188
  • 4
  • 68
  • 81
1

That catches a lot of folks out, the compulsion to catch nested exceptions like that.

You should log it, ideally using something robust like Log4J, but otherwise I would say it's safe to ignore it, other than a comment saying "deliberately ignoring".

Brian
  • 6,391
  • 3
  • 33
  • 49
1

There is nothing you can do with the exception thrown by close except catch it and log it. The important thing is that if you were to let it be thrown, and if there was another exception that was thrown before the close method was reached, the close method could throw an exception that would mask the first exception, it wouldn't show up anywhere and you wouldn't know what the real problem was. So you definitely don't want that.

Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276