简体   繁体   中英

Anything I can do when socket.close() throws in Java?

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?

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.

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.

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.

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.

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".

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM