Is it considered bad programming to write a try and catch within a finally clause?
I'm having in my main method a fileInputStream which I want to close.
I want to place the .close() in the finally, so it will close no matter what. I don't want to add a throws declaration to the main method, as it is the main method :P
}finally{
try {
commandFile.close();
} catch (IOException e) {
throwException(e);
}
}
is it ok?
Thanks
The pattern of needing try/catches in finally methods is unfortunately a recurring pattern in Java 6 and before. I would argue that it actually IS a bad practice, but not one that you can really avoid in Java 6 (see below for Java 7).
An addition problem is that any new exceptions thrown in the finally block will override exceptions that were thrown before reaching this block.
In Java 7 there is specifically for the cases where resources need to be closed (the majority of the use cases for try/finally/try/catch constructs) the new try-with-resources construct. This will also capture both the primary and secondary exceptions.
Using this construct is thus now a best practice in JDK 7 and yes, the code you show is thus a bad practice in Java 7.
Related
This question already has answers here:
Try-catch: is this acceptable practice?
(8 answers)
Why are empty catch blocks a bad idea? [closed]
(20 answers)
Closed 9 years ago.
Say I have a try statement with and empty catch is that bad practice? For example say I have 2 try separate trys where it is possible for one to fail but the other to succeed or both succeed or any possible combination of such. Is that bad practice to handle code like that?
Example
if( mode == Modes.EDIT ){
try {user = userBo.findById(id).get(0); }
catch(Exception e) { }
try{
result = this.initializeEntityById(accountDao, id);
if( !result.equals(SUCCESS) ){
return result;
}
}
catch(Exception e){ }
}
In this example the variable in concern is 'id' where I'm not sure if the value coming in is valid and on the front end it doesn't really matter because the code handles whatever comes in and provides correct display.
So the question really is:
Is this a bad practice with the empty catch's?
Is there any potential instability that could occur that I'm not realizing?
Is there a better way to achieve what I'm looking to get at?
Yes it's always bad practice since you have no idea what went wrong where. You should at least log the exception.
The instability is that when something goes wrong, you have no idea what is wrong with your code.
It's never desirable to use exceptions for control-flow. The performance is atrocious, and exceptions should only be used for exceptional circumstances. Here's what you can do:
Make the exception part of the method signature and let a higher level handle it.
Catch the exception, but wrap it in a semantically-appropriate exception and rethrow it so a higher level can handle it.
Handle it. This can also be done in multiple ways:
Don't let the exception happen: instead of catching the exception, perform an inspection on the data to see if it can cause an exception. For example, in your case I think you should have a method like userBo.existsWithId(id) which will return a boolean that says whether the user exists. Or have the findById return null if the user cannot be found, and check to see if user == null. I think this is your best bet.
Recover from the exception in some sane way (depends on your business logic).
This is bad practice.
There's no instability, per se, but with empty catches, nothing is being done about the exception, which could leave an object in an inconsistent state if some aspects didn't get processed due to the exception.
With that said, empty catch blocks make for very difficult debugging. Even in production code, you should include a basic "notification" for most exceptions.
In testing code, use e.printStackTrace( in every catch block that does nothing otherwise.
1) Is this a bad practice with the empty catch's?
Yes this is not a good practice.
2) Is there any potential instability that could occur that I'm not realizing?
If you anything goes wrong and any exception thrown then you will not be able to identify what goes wrong because in catch block you are not doing anything so it is assumed to be handled.
3) Is there a better way to achieve what I'm looking to get at?'
Try to log the exception stacktrace in catch block . or throw it again
e.g. e.printstacktrace();
Yes, this is bad practice.
If an exception is thrown, it should be handled somehow, and the catch block is meant to hold the handling code. At the very least, if you don't need recovery code and alternate logic in your method to handle a caught exception (which would be rare), you should log the exception so you know it happened.
You can read an excellent article on handling exceptions here:
http://www.onjava.com/pub/a/onjava/2003/11/19/exceptions.html?page=2
I found the second page to be especially helpful.
This question already has answers here:
Is a finally block without a catch block a java anti-pattern?
(12 answers)
Closed 9 years ago.
What is the best practice in using Try Catch Finally block? Do you prefer to use only try finally block and not try catch block? I always thought that try catch finally is the best practice to use. However, in part of the code I am working with I have seen code like this:
try{
doSomething();
}
finally{
doSomethingElse();
}
Since they don't catch the exception it was really hard for me to debug the code. It wasn't a really good practice to me not using catch and only finally, but I might be wrong.
To best of my understanding, this is not really a good practice. Basically, we are not making use of what try catch was intended to be used for. I have found similar questions as well.
My questions is: "Do you agree with me on the following hypothesis: The best practice is to use try catch finally together and not try finally." If you do not agree, would you please provide me with an example of when to use try finally instead of try catch finally and why you think try finally is better than try catch?
I disagree, if you cannot do anything about an exception being thrown, but something further up your caller hierarchy can, then use the finally to clean up your resources and let the caller deal with cleaning up after the exception is thrown.
The purpose of the finally construct is to provide code that will always execute, even if an exception is thrown.
The try / finally (no catch) allows you to write code that is guaranteed to execute even if a runtime exception is thrown by the code inside the try block.
This is good in situations where you are using code that might throw runtime exceptions but does not throw checked exceptions. An example of this is Spring DAO support; which wraps IOExceptions in runtime exceptions.
Generally try-finally is used to assure that some piece of code gets executed irrespective if the exception occurs or not.
Catch block is generally missing because code in try block does not throw any checked exception which can be caught.
Eg:
try {
if(str.length() > 0) { // If str is null, it can throw NullPointer and hence code below it wont execute
// some code
}
}finally {
// Will be performed even if any unchecked exception is thrown
// Must contain code which has to be performed at any cost like releasing occupied memory
}
There are three possibilities, try+catch, try+finally, or try+catch+finally. They all have their uses.
Use the catch with try when there's something you can usefully do to handle the exception, such as report the fact that the exception has occurred.
The code inside the finally block always runs, independent of whether an exception occurs or not, so use finally with try when there's cleaning up to do that's always got to happen. An example would be closing a file if it's been successfully opened.
I do not agree.
try{}finally{} should be used in cases where you cannot handle the exception, but are required to clean up resources.
A try{}finally{} block will not cause the exception to "disappear" as you seem to think it will. It will be thrown up the stack and be handled somewhere else. If you are unable to see the exception in your current application it's because it's being thrown away elsewhere.
try {
connection = createConnection();
}
finally {
closeConnection(connection) //Free database connection.
}
In this case, you may not have any ability to handle an SQL exception, but you still want to free the database connection.
I wonder if the following two swnippest are semantically identical, and, if not, what are the differences (we assume that we want to compute a result of type R, and want to guard against exception X that may be thrown in the course of doing so):
public R tcf(....) {
try {
R some = ...;
... compute the result ....
return some;
}
catch (X exception) {
... exception handling ....
}
finally {
... clean up ....
}
}
and the following:
public R tc(....) {
try {
R some = ...;
... compute the result ....
return some;
}
catch (X exception) {
... exception handling ....
}
}
public R tf(....) {
try {
return tc(....); // wrap the try-catch in tc()
}
finally {
... clean up ....
}
}
As far as I can see, it boils down to if a try-catch block wrapped in a try block with finally is the same, semantically, as a try-catch-finally block, assuming that the code in the finally and catch phrases stays the same and the outer try block just promotes the result of the inner one.
Practical relevance: Given a code base that does not make use of try-catch-finally, when it should, and given that for some reason, one cannot toch that code, one could more or less mechanically generate a layer of wrapper methods that add the finally.
I am fully aware of the fact, that for many reasons, one should use the try ... catch ... finally whenever possible. Specifically, I am not suggesting in any way that one should refactor the first example so that it looks like the second.
Rather, I want to make sure that example 2 can safely be refactored to example 1.
Functionally, they are equivalent.
I think it's good style to perform cleanup in the same method that has allocated the resources in question. In some cases this is the only practical way to go about things (for example, if the cleanup involves variables that are local to tcf/tc).
Also, if tc doesn't clean up after itself, the cleanup becomes part of the function's contract, as a caller's obligation. This makes the design more error-prone, since the cleanup is easy to forget or get wrong. Additionally, if the steps involved in the cleanup in any way change, every single caller would need to be tracked down and updated.
Bottom line: if the cleanup can be performed in tcf, it should be.
They are the same, however. The try/finally should always be right after the recourse (that finally releases) is claimed. (note that this happens just before the try)
For example:
getLock();
try {
doSomething()
}
finally {
releaseLock();
}
Because it is really easy to forget to clean up, it should always happen at the same location as the taking of the resource. Reason for this is that you should never burden your callers with something they always have to do (and you can do yourself)
Not performing the finally in the same method as the try/catch leaves you open to the method doing the try/catch at some point being called without the finally being executed, which is likely a bug.
I'd therefore not advise you to write it like that, though in the scenario you describe, having to add functionality through a finally when the method containing the try/catch can't be modified, it's the only way.
I think your description is pretty accurate in that the tf finally will execute in both cases and that the exception handling will be dealt with in either tcf or tf catch block.
That is, in example (1): if an exception occurs in your try, flow will execute your catch block followed by your finally block. In example (2), in tc, if an exception occurs in your try block, flow will continue in your catch block and then (presuming the exception isn't re-thrown) return to the calling line in tf. On completion of your tf try block, flow will continue in your tf finally block.
I guess the main implication to be aware of, and that you may not be able to correct in the way you suggest, is that:
If you implement your code as in your second example, you won't be able to necessarily access the tc resources from tf to be able to clean them up.
Even if you can, you're cleaning up resources at a layer that is not close to the resource usage and may not even be used by other client code of the framework. I guess that's a question of documentation and training.
Both are identical. but finally is used when you are having a risk of breaking the function in between or want to release some resources held by the function. in that case catch is skipped but finally will definitely execute.
try can be used either with catch or finally or both. finally generally can't show the exception occurred but catch can trace the exception.
We have received Java code from a software supplier. It contains a lot of try-catch blocks with nothing in the catch part. They're all over the place. Example:
try {
spaceBlock.enable(LindsayModel);
} catch (Exception e) {
}
My questions are: Is the above acceptable practice? If so, when? Or should I just go ahead and remove all of these "bogus" try and catch statements?
To me this looks like terrible practice, but I'm not experienced enough in Java to tell for sure. Why catch errors if you're not going to do anything with them? Seems to me, you would only do that if you were confident that an exception would be of absolutely no consequence and you don't care if one occurs. However, this is not really the case in our particular application.
EDIT To give some context: We bought a Java-scriptable product from the supplier. Alongside the product, they provided a large proof-of-concept script tailored to our needs. This script came "free of charge" (though we wouldn't have bought the product if it hadn't come with the script) and it "works". But the script is a real pain to build upon, due to many things that even I as a Java novice recognise as awful practice, one instance being this bogus try-catch business.
This is indeed terrible practice. Especially the catching of Exception rather than something specific gives off a horrible smell - even a NullPointerException will be swallowed. Even if it is assured that a particular thrown exception is of no real consequence, one should always log it at the very least:
try {
// code
}
catch (MyInconsequentialException mie) {
// tune level for this logger in logging config file if this is too spammy
MY_LOGGER.warning("Caught an inconsequential exception.", mie);
}
However it is unlikely an exception is completely meaningless in this situation. I recommend researching exactly what exception(s) the application's code is intending to swallow here, and what they would really mean for the execution.
One important distinction is whether the try/catches are used to swallow checked exceptions. If this is the case, it probably indicates extreme apathy on the programmer's part - somebody just wanted his/her code to compile. At the least, the code should be amended:
try {
// code
}
catch (SpecificCheckedException sce) {
// make sure there is exception logging done farther up
throw new RuntimeException(sce);
}
This will rethrow the exception wrapped in an unchecked RuntimeException, effectively allowing the code to compile. Even this can be considered a bandaid however - best practice for checked exceptions is to handle them on an individual basis, either in the current method or farther up by adding throws SpecificCheckedException to the method signature.
As #Tom Hawtin mentioned, new Error(sce) can be used instead of new RuntimeException(sce) in order to circumvent any additional Exception catches farther up, which makes sense for something that isn't expected to be thrown.
If the try/catch is not being used to swallow checked exceptions, it is equally dangerous and should simply be removed.
Terrible, indeed. Swallowing an exception like this can be dangerous. How will you know if something bad has happened?
I'd feel better if the vendor wrote comments to document and acknowledge it ("We know what we're doing"). I'd feel even better if there was a strategy apparent in the code to deal with the consequences. Wrap it in a RuntimeException and rethrow; set the return value to an appropriate value. Anything!
"All over the place"? Are there multiple try/catch blocks littering the code? Personally, I don't like that idiom. I prefer one per method.
Maybe you should find a new vendor or write your own.
try {
meshContinuum.enable(MeshingModel);
} catch (Exception e) {
}
This looks like unfinished code. If the enable method throws an Exception then it will be caught and swallowed by the code. If it doesn't then it does not make sense to try to catch a non occuring exception.
Check to see the methods and where their signatures are not followed by throws exceptionName, then remove the empty try-catch statements from the places they are called.
You can theoretically put try-catch around any statement. The compiler will not complain about it. It does not make sense though, since this way one may hide real exceptions.
You can see this as a sign of bad code quality. You should probably be prepared to run into problems of different type too.
It's not the best:
It hides evidence of the exception so debugging is harder
It may cause features to fail silently
It suggests that the author might actually have wanted to handle the exception but never got around to it
So, there may be cases where this is OK, such as an exception that really is of no consequence (the case that comes to mind is Python's mkdirs, which throws an exception if the directory already exists), but usually, it's not so great.
Unfortunately you cannot just remove it, because it the try block throws a checked exception then it will have to be declared in the throws clause of the method. The callers of the method will then have to catch it (but not if the callers also have this catch (Exception e) {} abomination).
As an alternative, consider replacing it with
try {
meshContinuum.enable(MeshingModel);
} catch (Exception e) {
throw (e instanceof RuntimeException) ? (RuntimeException) e : new RuntimeException(e);
}
Since RuntimeException (and classes that extend it) are unchecked exceptions they do not need to be declared in the throws clause.
What did your contract with the supplier specify? If what they wrote, bad practice and all, meets the spec then they will charge you for a rewrite.
Better to specify a set of tests that will enter many or all of those try-catch blocks and hence fail. If the tests fail you have a better argument to make them fix their terrible code.
Horrible idea on the face of it, totally depends on what you're actually calling. Usually it's done out of laziness or habituated bad practices.
Actually ... not so fast.
There are legitimate cases for ignoring an exception.
Suppose that an exception has happened already, and we're already in a catch(). While in the catch(), we want to make best effort to clean up (which could fail, too). Which exception to return?? The original one, of course. The code looks like this:
try {
something-that-throws();
} catch(Exception e) {
try {
something-else-that-throws();
} catch(Exception e1) {}
throw e;
}
When we really don't care whether an operation succeeds, but (unfortunately) the operation's author throws an exception if a failure occurs.
if (reinitialize) {
try {
FileUtils.forceDelete(sandboxFile); // delete directory if it's there
} catch(Exception e) {}
}
The above saves a rather tortured attempt to see if sandboxFile actually exists before deleting it anyway.
In one of my Java application's code, I have a try-catch-finally block in which the try block creates some input and output streams and if something goes wrong I close any earlier opened streams in finally.
finally
{
if(inputStream != null)
inputStream.close();
if(outputStream != null)
outputStream.close();
}
But the <stream>.close() line in Eclipse shows error that "Unhandled exception IOException" in the code for this line and shows that the solution is to include another try/catch in the finally block which would seem to be bad as a programming practice and I don't want in finally block.
My question is: is it possible to remove this error in Eclipse and use try/catch only when I need it instead of eclipse telling me to do the try/catch add. (Since I am already trying to avoid exception by replacing try/catch with if/else as possible).
This is not an Eclipse error, it is a Java compiler error. Eclipse is merely reporting the Java compilation error for you. There is no way to "turn it off" as the code does not compile without the try/catch clause. It is a safety feature in Java that forces you to handle commonly thrown Exceptions.
Methods have Exceptions in their signature. For example, InputStream.close() throws an IOException, forcing you to handle it in a try/catch block.
public void close() throws IOException {
...
Throwing an Exception is a way of telling the program that a significant problem - that must be handled - has occurred.
My question is: is it possible to remove this error in eclipse and use try/catch when I need it otherwise not instead of eclipse telling me to do try/catch add.
No, it is not possible.
(Since I am already trying to avoid exception by replacing try/catch with if/else as possible).
You should generally never try to replace try/catch blocks with if/else blocks. They are two distinct features with distinct purposes.
Exceptions are an essential Java feature. Read about it and understand it.
Properly this should be done something like this to ensure that we attempt to close both streams.
finally
{
try {
if(inputStream != null)
inputStream.close();
}
catch(Exception e)
{ /* Ignore */ }
try {
if(outputStream != null)
outputStream.close();
}
catch(Exception e)
{ /* Ignore */ }
}
If you don't care about handling the exception, check out the Apache commons io library.
org.apache.commons.io.IOUtils.closeQuietly(inputstream)
Works for outputstream, writer and reader too.
IOException is not something that you can avoid because it might happen because of circumstances outside your control. (Broken network connection, hard drive error etc). Eclipse is totally right that inputStream.close() and outputStream.close() itself may throw exception, and you must be prepared to handle that somehow. There is no way to silence this error because it is not Eclipse's pickiness; your code is not valid Java code as it stands.
You may declare that your function throws IOException and delegate the handling of the exception to the caller, or you must bite the bullet and handle (and probably ignore) the IOException yourself. I think there is a utility function in the IOUtils library of Apache Commons that encapsulates this logic, which would make your code cleaner (and hide the fact that you are silently ignoring an IOException).
But the .close() line in eclipse shows error that Unhandled exception IOException in code for this line and shows solution to include another try/catch in finally block which is bad as programming practice and i don't want in finally block.
The fact that close methods can also throw IOExceptions, so that you have to have nested try/catch clauses inside the finally block, is an unfortunate situation.
But there is really nothing much you can do about this. You need those (ugly) finally blocks to handle exceptions properly.
There is nothing wrong with eclipse.It just show you have a compile error in your code.you cannot replace try-catch with if-esle and here it required try catch.You need this try catch not because the input stream may be null as you try in if else.