Anything I can do when socket.close() throws in Java? - 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.

Related

under which conditions can the error escape try-catch with Exception class?

Which error conditions will not be caught by this try-catch block?
try
{
//some codes
}
catch (Exception e)
{
//log error
}
Background:
I implemented a server which runs external executables (with ProcessBuilder). So basically, I don't want the errors in the try block to kill the server. Catching Throwable might be the better option here, but I would like to know what else can escape Exception or more robust alternatives if any. Thanks!
Anything that's not an Exception.
Take a look at https://docs.oracle.com/javase/7/docs/api/java/lang/Exception.html for Javas own Exceptions (you can create your own by extending the Exception class).
Take note also that there is a difference between Error and Exception.
https://docs.oracle.com/javase/7/docs/api/java/lang/Error.html
Also, how do you plan on recovering from all Exceptions that exists?
If an Exception is thrown, you have reached a state where something is terribly wrong. Not knowing what that wrong is, it can be very hard to actually recover, leaving your server in a non-functional state. So while your server doesn't die in the sense that you see an Exception (and by that can trace back what went wrong), you will most likely be in a non-functional state anyhow.
If you haven't already done so, take a look at https://docs.oracle.com/javase/tutorial/essential/exceptions/ for dealing with exceptions. Or read it for an refresher.

Java: How to continue reading a file after an exception is thrown

so my professor has assigned us a project where we have to take in commands from a text file and use them to drive the flow of our program. These commands such as- Takeoff, land, load cargo, unload cargo, etc.- are meant to simulate an airplane-like object.
Sometimes these commands don't make sense to execute, like loading cargo while a plane is in-flight. Therefore, to prevent something like that from happening we had to code in our own exception classes i.e. "If the plane is ordered to load cargo while in flight, throw InvalidActionException"
My question is: how can I continue to read-in commands from the text file after exceptions have been thrown (seeing as how once they are thrown, the program cannot progress further
Here's an outline of what I want to do:
Scanner input = new Scanner(new FileInputStream("stuff1.txt"));
while(input.hasNextLine())
{
try
{
//execute commands by reading them using input.nextLine()
}
catch()
{
//catch any exceptions and ignore them... continue to read
//the file for more commands
}
}
I would appreciate any help. Thanks.
Catch appropriate exception and flow will automatically reach while loop condition.
After cathing exception nothing extra to be done to continue the program.
seeing as how once they are thrown, the program ends abruptly
Only uncaught exception stop a thread. I suggest you catch all the exceptions you want to continue after and you won't have a problem.
Catch your specific exception:
while(input.hasNextLine())
{
try
{
//execute commands by reading them using input.nextLine()
}
catch ( UserDefinedException ex )
{
//catch the exceptions you're throwing
}
}
That's exactly what you want to do. All the reading and processing statements go in the try block, and the catch block just contains error processing (which may consist of nothing other than printing a warning message somewhere.
The thing you need to be careful of is that you don't get stuck in an endless loop. Make sure each time around the loop you're processing new data!
Since your catch is inside the while loop, the loop will naturally continue onto the next iteration after the exception has been caught.
Any exception caught in your catch block(s) will not cause the program to terminate. Simply catch the Exception(s) you want handled and your loop will continue.
while(input.hasNextLine())
try {
//execute commands by reading them using input.nextLine()
}
catch (CargoLoadingException e)
{
System.err.println("Can't load cargo while the plane is in flight.");
}
catch (OtherException e)
{
e.printStackTrace();
}
}
Note that if you catch Throwable, you basically catch any exception that can be thrown. However, you probably only want to catch specific exceptions. For example, PlaneCrashException probably should cause the program to terminate.
The outline you have shown is sufficient to achieve what you want (i.e. the try-catch-construct is inside the while loop). Just make sure that the catch statement declares the correct type or supertype of exception you want to catch-and-ignore.
UPDATE: If you are unsure about what kind of exception to catch, you might want to catch "Throwable", but this is not really recommended. When your teacher had you implement your own exceptions, you probably based them off one existing Exception class. You might want to catch that Exception type then.
And on a totally differnt note, you might want to read in the entirety of the commands from the text file into a list of strings before executing the sequence. This might save you from some IO problems, because you keep the file handle open all the time (which seems unnecessary for such a straight-forward task).
To add to the other answers: Exceptions can do a number of jobs. All too commonly, they tell you that your program is hopelessly unstable and should shut down immediately.
Normally, they tell you that something bad and unexpected happened, and give you a chance to explain the problem to the user and then carry on. For instance, an unexpected End-Of-File exception. You can tell the user the file is bad and let them try another one. You can also print out a stack trace so they can call you and you can figure out what happened even if you did not print an extensive error message.
Note the split personality of this exception. Like the first type (RunTimeException instances, usually), they let you know exactly what happened almost without you doing anything. However, Java also forced you to be aware that an IOException could be thrown and tried to force you to write a nice message for the user. I've always been a bit puzzled about this. If I catch an EOFException, I know where it happened and I don't need the stack trace. (Of course, if I know an EOF cannot happen, I'm not going to bother with a proper message to the user, and the stack trace when it does happen will be very handy.)
But there's a third sort of an exception, sort of the second personality of the previous exception. It just lets you know something perfectly normal happened. It is highly efficient (if you set it up right; see below). And it can be a lot cleaner than returning values up a stack of method calls. It allows a method that already returns, say, a String (with a null reference being perfectly okay) to alert the calling method to a special condition and, optionally, provide vast amounts of data on that condition.
public static class MyEOFException extends EOFException {
// Saves creating a meaningless stack trace.
public Throwable fillInStackTrace() { return this; }
}
// Saves creating a new object every time you use it
public static MyEOFException myEOF = new MyEOFException();
Then, inside a method:
try {
for (;;) {
String text = readAStringFromFile( in );
// Do something with text...
}
}
catch (MyEOFException e) {
// Nothing at all needs to be done here.
// Note that MyEOFException COULD have beeen set up with tons of data and
// then a lot of work could be done. (The file might end with binary
// data, for instance, which would be in "e".)
}
The exception could be thrown many levels down and it will pop you out of the loop quite neatly. In most such cases, this would be a little too simplistic. Often it's too complicated; try-catch blocks can be annoying. Something like:
while (readAStringFromFile( in ));
is a lot nicer and faster to write if readAStringFromFile has a place to put what it read.
In your particular case, using exeptions like this may be what your professor is looking for. My personal experience is that there is almost always a better way to do it than with try-catch blocks, but when they do work they work really well.

Catching exceptions caused by temporary network errors

I have to download some URLs, and it can happen that during the operations some exception may occur, like java.net.NoRouteToHostException. I consider it a temporary error exception, as the download can succeed if you retry it after some time.
So, I'd like to catch all those exceptions related to temporary errors, and I've started with these: java.net.NoRouteToHostException, java.net.SocketException
Can you list other exceptions like these?
java.net.SocketException is the parent of java.net.NoRouteToHostException so you could maybe catch only the parent. The others childs of SocketException are BindException, ConnectException and PortUnreachableException. Maybe it's ok to catch only SocketExceptionin your case...
One pattern which is sometimes useful for dealing with transitory errors on retry-able operations is to define an error-callback interface and some classes that implement it; when an error occurs, let the callback object know, and let it decide whether an exception should be thrown or the action should be retried. Because the existing communications classes don't follow such a pattern, it may be necessary to catch their exceptions and turn them into callbacks.
Note that this approach allows much cleaner handling of many error-handling scenarios than would normal exception handling. Among other things, it makes it easy to set policies for how many retries may be attempted, how long they may take, etc. and also provides a means of skipping future retries if something like a "cancel" request is received.
As #reef has already said java.net.NoRouteToHostException exntends java.net.SocketException, so if you catch java.net.SocketException it is enough. But java.net.SocketException extends IOException and I think that this is what you really should to catch. All IO problems should throw this exception.
HttpRetryException is another. Maybe everything in java.net that does not extend SocketException?
One quick (and very dirty) way could be
try {
....
} catch(Exception e) {
if(e.getClass().getPackage().getName().equalsIgnoreCase("java.net")) {
retry();
}
}

Why is the Catch(Exception) almost always a bad Idea?

Why is the catch(Exception) almost always a bad Idea?
Because when you catch exception you're supposed to handle it properly. And you cannot expect to handle all kind of exceptions in your code. Also when you catch all exceptions, you may get an exception that cannot deal with and prevent code that is upper in the stack to handle it properly.
The general principal is to catch the most specific type you can.
Short story: it's called bug masking. If you have a piece of code which is not working well and throwing exceptions (or you pass malformed input to that piece of code) and you just blind your eyes by catching all possible exceptions, you will actually never uncover the bug and fix it.
You should only catch exceptions if you can properly handle them. As you cannot properly handle all possible exceptions you should not catch them :-)
It depends on what you need. If you need to handle different types of exceptions in different ways then you should use multiple catch blocks and catch as much specific exceptions as you can.
But sometimes you may need to handle all exceptions in the same way. In such cases catch(Exception) may be ok. For example:
try
{
DoSomething();
}
catch (Exception e)
{
LogError(e);
ShowErrorMessage(e); // Show "unexpected error ocurred" error message for user.
}
Because you don't really know why an exception happened, and several exceptions require very special car to be handled correctly (if possible at all), such as a OutOfMemoryException and similar low-level system exceptions.
Therefore, you should only catch exceptions:
which you know exactly how to deal with it (e.g. FileNotFoundException or so)
when you will re-raise them afterwards (for instance to perform post-fail cleanup)
when you need to transport the exception to another thread
I find two acceptable uses of catch(Exception):
At the top level of the application (just before returning to the user). That way you can provide an adequate message.
Using it to mask low-level exceptions as business ones.
The first case is self-explanatory, but let me develop the second:
Doing:
try {
// xxxx
} catch(Exception e) {
logger.error("Error XXX",e)
}
is bug masking like #dimitarvp said.
But the below is different:
try {
// xxxx
} catch(Exception e) {
throw new BusinessException("Error doing operation XXX",e)
}
This way you aren't ignoring bugs and hiding them under the carpet. You are providing a high-level exception with a more explanatory message to higher application layers.
It's also always important to manage exceptions at the correct layer. If you escalate a low-level exception to a high business layer, it's practically impossible for the higher layer to manage it well.
In that case, I prefer to mask the low level exceptions with a business one that provides a better context and message and that also has the original exception to be able to go into the details.
Even so, if you can catch more concrete exceptions and provide better treatment for them you must do it.
If in a block of code you can get an SQLException and a NetworkException you must catch them and provide adequate messages and treatment for each of them.
But if at the end of the try/catch block you have an Exception mapping it to a BusinessException it's ok for me.
In fact, I find it adequate when higher service layers only throw business exceptions (with details inside).
Besides what yet answered by #anthares:
Because when you catch exception you're supposed to handle it properly. And you cannot expect to handle all kind of exceptions in your code. Also when you catch all exceptions, you may get an exception that cannot deal with and prevent code that is upper in the stack to handle it properly.
The general principal is to catch the most specific type you can.
catch(Exception) is a bad practice because it catches all RuntimeException (unchecked exception) too.
This may be java specific:
Sometimes you will need to call methods that throw checked exceptions. If this is in your EJB / business logic layer you have 2 choices - catch them or re-throw them.
Catching specific exception classes means you will need to re-analyze your actions for which exceptions can be thrown when you look to see how this code handles exceptions. You will often get into a "what if..." situation and it can be a lot of effort just working out if exceptions are handled correctly.
Re-throwing means that code calling your EJBs will be littered with catching code that will typically not mean anything to the calling class. n.b. throwing checked exceptions from EJB methods will mean that you are responsible for manually rolling back any transactions.
But sometimes it is OK! Like if you have a piece of code that does something 'extra', which you really don't care about, and you don't want it to blow up your application. For example, I worked on a large application recently where our business partners wanted a certain daily transaction to be summarized in a new log file. They explained that the log wasn't all that important to them, and that it did not qualify as a requirement. It was just something extra that would help them make sense of the data being processed. They did not need it, because they could get the information elsewhere. So that is a rare case where it is perfectly fine to catch and swallow exceptions.
I also worked at a company where all Throwables were caught, and then rethrown inside a custom RuntimeException. I would not recommend this approach, but just pointing out that it is done.
Isn't it another valid scenario to ensure that a thread keeps alive catching exception inside it?
Thread shouldRunWhenApplicationRuns = new Thread() {
#Override
public void run() {
try {
// do something that should never end
} catch (Exception ex) {
// log it
}
};
shouldRunWhenApplicationRuns.start();
Sonar has also a good Explanation, why this is not a good idea, and how it can be prevented:
https://rules.sonarsource.com/java/RSPEC-2221
Catching Exception seems like an efficient way to handle multiple possible exceptions. Unfortunately, it traps all exception types, both checked and runtime exceptions, thereby casting too broad a net. Indeed, was it really the intention of developers to also catch runtime exceptions? To prevent any misunderstanding, if both checked and runtime exceptions are really expected to be caught, they should be explicitly listed in the catch clause.

Catching exceptions in Java

There are certain predefined exceptions in Java, which, if thrown, report that something serious has happened and you'd better improve your code, than catching them in a catch block (if I have understood it correctly). But still I find many programs in which I have the following:
} catch (IOException e) {
...
} catch (FileNotFoundException e) {
....
}
and I thought that IOException and FileNotFoundException are exactly such kind of exceptions, which we shouldn't catch in a catch block. Why people do this? Is it better to catch them like this? Java compiler warns anyway about any problem of that kind.
Thank you.
No, there's nothing wrong with catching IOException and FileNotFoundException - if you can genuinely handle those exceptions. That's the important bit - can you really proceed in the face of that exception? Sometimes you can - very often at the top level of a server, for example, where just because one request fails doesn't mean the next can't proceed. Less often in client apps, although it very much depends on the situation. Can't read a file when you're trying to do a batch import? Okay, abort the operation but don't necessarily shut down the whole process...
You shouldn't have them that way round, admittedly - the FileNotFoundException would be masked by the IOException which it derives from. Fortunately the compiler flat-out prevents you from doing this.
The order that you show, with IOException caught before FileNotFoundException is wrong. Since FileNotFoundException extends IOException, when a FileNotFoundException is thrown, the first handler will be used, and the second handler is dead code.
I haven't tried it, but I'm a little surprised if this compiles. A static analysis tool like FindBugs would catch this error, I hope.
As far as whether you should catch a FileNotFoundException, it depends on the caller. However, I will say that a FileNotFoundException can often be recovered in a meaningful way—prompting for another file, trying a fallback location—rather than simply logging the error or aborting the process.
There are two types of exceptions in Java, checked exceptions and unchecked exceptions.
Checked exceptions must be handled in a catch block. Not doing this will cause a compiler error. IOException is an example of a checked exception, and must be handled. What you actually do here depends on the application in question, but the Exception must be handled to keep the compiler happy.
Unchecked exceptions do not need to be caught. All classes that extend from RuntimeException are unchecked. A good example of this is a NullPointerException or an ArrayIndexOutOfBoundsException. The compiler doesn't force you to catch these exceptions, but they may still occur when your program runs, causing it to crash.
For the record, IOException can be thrown for something as simple as trying to open a file that doesn't exist. It is a good idea to handle something like this and recover gracefully (dialog to the user saying the file doesn't exist and make an open file dialog reappear or something), rather than letting the program crash.
The do this in order to handle different types of exceptions differently.
Typically you are going to want to catch the most granular exceptions first, if you put the more broad exceptions at the beginning of your catch block, you will execute that code first, then hit the finally block.
Jon is right, the catch that catches the IOException will catch all IOExceptions and any sub-type of IOException, and since FileNotFoundException is a type of IOException, it will never hit the 2nd catch.
As Jon says, catching these exceptions is fine in many cases. The kind of exceptions that you shouldn't be catching are things like NullPointerException and ArrayIndexOutOfBoundsException, these indicate bugs in your code.
Java has two types of exception: checked exceptions and unchecked exceptions (those that inherit from RuntimeException).
Checked exceptions, such as IOException, are usually used for unpredictable scenarios that can't be avoided by writing better code. The fact that they are checked means that the compiler forces you to write code that accounts for the possibility of the exceptional scenario. For example, you have to consider the possibility of a FileNotFoundException because you can't guarantee that the file will exist (somebody might move it while your program is running). An IOException might occur because a network connection gets dropped. The compiler forces you to provide a strategy for dealing with these cases, even if it's just to pass the buck by allowing the exception to propagate up the stack for calling code to handle.
Unchecked exceptions on the other hand are best used for things that can be avoided by changing the code. A NullPointerException can always be avoided if the code makes a check for the possibility of a null reference. Likewise, if you are careful with your indices, you will never get an ArrayIndexOutOfBoundsException. The compiler doesn't oblige you to handle these scenarios since they represent bugs that should be fixed.
I thought that IOException and FileNotFoundException are exactly such kind of exceptions
Nope, those are actually the "other" type of exceptions, the kind that go beyond your programming skills. No matter how good do you program, the compiler and the libraries make you be "conscious" that something might happen.
Think about this scenario:
You create an application that saves data to a temp folder.
Everything is alright, you have checked the folder exists, and if not, you create it your self.
And then you're writing 2 mb to that temp folder.
Suddenly, other system process, deletes your temp folder, and you cannot write anymore.
There is nothing you can do to prevent this programmatically, in some systems that operation could happen ( In unix the root user may perform rm -rf /tmp and there is nothing you can do about it. In windows I think the system won't let other process delete a file is is being used )
By forcing you to check this kind of exceptions in the code, the platform designers thought that at least you're aware of this.
Jon is correct sometimes there is nothing you can do about it, probably logging before the program dies, that is considered as "handle the exception" ( poor handle yes, but handle at least )
try {
....
} catch( IOException ioe ) {
logger.severe(
String.format("Got ioe while writting file %s. Data was acquired using id = %d, the message is: %s",
fileName,
idWhereDataCame,
ioe.getMessage()) );
throw ioe;
}
Another thing you can do is to "chain" the exception to fit the abstraction.
Probably your application, is has a GUI, showing a IOException to the user won't mean anything or could be a security vulnerability. A modified message could be sent.
try {
....
} catch( IOException ioe ) {
throw new EndUserException("The operation you've requeste could not be completed, please contact your administrator" , ioe );
}
And the EndUserException could be trapped somewhere in the gui and presented to the user in a Dialog message ( instead of just disappearing the app in his eyes without further information ). Of course there was nothing you can do to recover that IOException, but at least you die with style :P
Finally a client code, could use different implementations, and not all the exceptions would make sense.
For instance, think again on the fist scenario. That same "operation" could have three kinds of "plugins" services to perform the data saving.
a) Write the data to a file.
b) Or, write to a db
c) Or write to a remote server.
The interface should not throw:
java.io.IOException
java.sql.SQLException
nor
java.net.UnknownHostException
But instead something like
my.application.DataNotSavedException
and the different implementations would handle the exception at the correct level, and transform it to the appropriate abstraction:
Client code:
DataSaver saver = DataServer.getSaverFor("someKeyIdString");
try {
saver.save( myData );
} catch( DataNotSavedException dnse ) {
// Oh well... .
ShowEndUserError("Data could not be saved due to : " dnse.getMessage() );
}
Implementation code:
class ServerSaver implements DataSaver {
....
public void save( Data data ) throws DataNotSavedException {
// Connect the remore server.
try {
Socket socket = new Socket( this.remoteServer, this.remotePort );
OuputStream out = socket.getOut....
....
....
} catch ( UnknownHostException uhe ) {
// Oops....
throw new DataNotSavedException( uhe );
}
}
}
FileSaver and DatabaseSaver would do something similar.
All of these are Checked Exceptions because the compiler make you check them.
When to use one or the other ( checked / unchecked): here
There are other two kinds: here
And finally a much simpler explanation of the Runtime is: here
To take this idea sideways a bit: maybe in another domain it is clearer
What do you do if the car in front of you stops suddenly.
Stop!
So we handle the exception.
So back to code:
What do you do if the file you need is not available ?
either
Have a backup. Compiled in as a
resource because it's part of your
program. I'm not kidding.
IFF It's a user supplied file :Tell the user; it's their file.
Abort the program with a message to the user because your software SYSTEM is
broken.
It is my opinion that there is no fourth option.
Our C#/VC++ brethren choose unchecked exceptions. Many "experts" think checked exceptions are bad: my contention is that life is difficult, get over it.
Checked exceptions represent known failure modes: and have to be addressed.
Your fishbone diagram has a straight lie for normal operation and branches off the side for failures. Checked exceptions are the anticipated failures.
Now, once you start handling Runtime exceptions, then it gets interesting.
A Java program can run mostly normally with functions that do not work.
By this, I mean they throw null pointer exceptions, array bounds errors, invalid arguments, and run out of heap space. This makes incremental delivery quite feasible.
(If you ever do catch Runtime errors, log them. Otherwise you never know to fix things)

Categories

Resources