I am using SonarQube for code quality. I got one issue related to exception handling, which says remove throw clause from finally block.
} catch(Exception e) {
throw new MyException("request failed : ", e);
} finally {
try {
httpClient.close();
} catch (IOException e) {
throw new MyException("failed to close server conn: ", e);
}
}
Based on my understanding above code looks good. If I remove throw clause and suppress exception in finally then caller of this method will not be able to know server's status. I am not sure how we can achieve same functionality without having throw clause.
Your best shot is to use the Automatic Resource Management feature of Java, available since Java 7. If that is for some reason not available to you, then the next best thing is to replicate what that syntactic sugar expands into:
public static void runWithoutMasking() throws MyException {
AutoClose autoClose = new AutoClose();
MyException myException = null;
try {
autoClose.work();
} catch (MyException e) {
myException = e;
throw e;
} finally {
if (myException != null) {
try {
autoClose.close();
} catch (Throwable t) {
myException.addSuppressed(t);
}
} else {
autoClose.close();
}
}
}
Things to note:
your code swallows the original exception from the try block in case closing the resource fails. The original exception is surely more important for diagnostic;
in the ARM idiom above, closing the resource is done differently depending on whether there already was an exception in the try-block. If try completed normally, then the resource is closed outside any try-catch block, naturally propagating any exception.
Generally, methods in the finally block are 'cleanup' codes (Closing the Connection, etc) which the user does not necessarily need to know.
What I do for these exceptions is to absorb the exception, but log the details.
finally{
try{
connection.close();
}catch(SQLException e){
// do nothing and just log the error
LOG.error("Something happened while closing connection. Cause: " + e.getMessage());
}
}
You're getting a warning because this code could potentially throw an exception while dealing with a thrown exception. You can use the try with resource syntax to close the resource automatically. Read more here.
In the case that the "request failed : " exception is thrown and you fail to close the httpclient, the second exception is the one that would bubble up.
I am not sure how we can achieve same functionality without having
throw clause.
You could nest the two try blocks differently to achieve the same result:
HttpClient httpClient = null; // initialize
try {
try {
// do something with httpClient
} catch(Exception e) {
throw new MyException("request failed : ", e);
} finally {
httpClient.close();
}
} catch (IOException e) {
throw new MyException("failed to close server conn: ", e);
}
Related
I find myself coding methods that throw a specified error, but still surrounding the relevant code sections in a try catch, where I use the catch to log a localised error message and re-throw the principal one.
Here is a short example:
public void doWork(String url) throws IOException {
Object target;
try {
target = new target(url); //instantiating this object could potentially not work if the URL is malformed
} catch (MalformedURLException e) {
localErrorMessage(debug, "URL error here"); //log a local message
throw e;
} catch (IOException e) { //in some cases it can throw an IO exception if using a localised file type object.
localErrorMessage(debug, "IO error here"); //log a local message throw e;
}
}
I use this as I can turn off my localised logging (using log4j2), or use it during testing, as a debugging method.
Is this a reasonable practice, or is there a better way to do it?
Just came across a rather confusing exam question, and my lecturer is away on holidays, so I come to StackOverflow begging for help!
The question is as follows :
"Joe has his own JoeConnection class for making connections between his computer and other computers. The class provides the following constructor and instance methods :
JoeConnection( String address ): Make a connection with the URL address.
void writeLn( String text ) : Write text to the JoeConnection.
String readLn( ): Read a line of text from the JoeConnection.
void clode( ) : Close the JoeConnection.
Joe's connections regularly fail and this causes errors. Using proper exception handling, demonstrate how to use Joe's JoeConnection class to
make a JoeConnection with the URL http://students.chat.box
write "Hello world" to the JoeConnection
read in a string from the JoeConnection
close the connection.
The connection handling should provide as man details as possible about the cause of failure and print the stack trace which led to the failure.
I have no idea how to tackle this, but I assume it is something similar to this :
public class Test {
try {
JoeConnection connection = new JoeConnection(http://students.chat.box);
} catch {
connectionError e; printStacktrace();}
}
}
Can anyone please help me figure this out? Thanks a lot.
Without an indication of what exceptions are thrown and why, the only proper exception handling is no handling at all. Don't catch an exception if you don't know how to fix the problem that triggered it.
But the further instructions in your assignment introduce a different notion of "proper." You're supposed to print a stack trace. So catch the exception and print a stack trace. You were on the right track, but your syntax was wrong. Refer back to your textbook and lecture notes to remind yourself what the syntax is for catching exceptions (and for passing strings to functions, for that matter).
try {
JoeConnection connection = new JoeConnection("http://students.chat.box");
connection.writeLn("Hello world");
// etc
} catch (Exception e) {
e.printStackTrace();
}
"Proper exception handling" is a little vague. I agree with #Rob Kennedy's statement that no exception handling is appropriate unless you know why the exception is thrown and what should be done with it. Otherwise, the exception should be allowed to propagate. So, for example:
void foo(String address) throws JoeException {
JoeConnection connection = new JoeConnection(address);
try {
connection.writeLn("Hello World!");
} finally {
// Ensure the connection is closed when finished.
// This happens whether an exception occurs or not.
connection.close();
}
}
If you wanted to catch the exception just to print it, you could do something like this:
void foo(String address) throws JoeException {
try {
JoeConnection connection = new JoeConnection(address);
try {
connection.writeLn("Hello World!");
} finally {
connection.close();
}
} catch (JoeException e) {
e.printStackTrace();
// Don't know what to do about this; rethrow.
throw e;
}
}
There is a subtlety here that even experience Java programmers can miss, though. If an exception occurs while creating the connection, it doesn't need to be closed. If an exception occurs while writing to the connection, it does need to be closed; thus the finally clause. However, the act of closing can also throw an exception. If closing the connection throws an exception, only that exception will be thrown by the try statement. If the finally clause was reached as a result of the writeLn operation throwing an exception, the exception of the writeLn call will be effectively ignored. This is probably not what you want.
Instead, we can try something ugly like this:
void foo(String address) throws JoeException {
try {
JoeConnection connection = new JoeConnection(address);
boolean normalCompletion = false;
try {
connection.writeLn("Hello World!");
normalCompletion = true;
} finally {
if (normalCompletion) {
// The writeLn operation completed normally.
// Propagate an exception thrown by the close operation.
connection.close();
} else {
// The writeLn operation completed abruptly.
// Ignore an exception thrown by the close operation.
try {
connection.close();
} catch (JoeException e) {
/* empty */
}
}
}
} catch (JoeException e) {
e.printStackTrace();
// Don't know what to do about this; rethrow.
throw e;
}
}
This looks (and is) syntactically hideous, but it does show "proper" exception handling of a sort. The language enhancement from Project Coin should clean this up a bit.
For starters, I can help you out with the syntax of what you wrote:
try {
JoeConnection connection = new JoeConnection("http://students.chat.box");
}
catch (JoeConnectionException e) {
e.printStacktrace();
}
I took the liberty of changing the linebreaks and renaming 'connectionError' as JoeConnectionException which looks more conventional to me.
You'll have to do something similar for the readLn, writeLn, and close method calls since it said that the connection regularly fails (i.e. not just while connecting).
Cheers, good luck.
Catching an exception should look like:
try {
JoeConnection conn = new JoeConnection(url);
} catch (YourExceptionClassNameHere e) {
e.printStackTrace();
}
Also: if you want to use a literal String, make sure you include the quotations. (It should be "http://students.chat.box".)
It's good to have a finally as well:
public class Test {
try {
JoeConnection connection = new JoeConnection(http://students.chat.box);
}
catch(Exception e) {
e.printStacktrace();
}
finally {
if(connection != null) {
connection.close();
}
}
}
Typically you handle exceptions if you know what to do with them (this involves error-recovery logic or wrapping an exception and throwing it to a higher level).
Assuming that each method throws an exception, you could do something like this for "maximum detail":
public class Test {
JoeConnection connection = null;
try {
connection = new JoeConnection("http://students.chat.box");
...
...
}
catch(OpenException e) {
System.out.println("Error while opening connection");
e.printStacktrace();
}
catch(WriteException e) {
System.out.println("Error while writing to connection");
e.printStacktrace();
}
catch(ReadException e) {
System.out.println("Error while reading from connection");
e.printStacktrace();
}
finally {
if(connection != null) {
connection.close();
}
}
}
I have the following code:
try {
DOMConfigurator.configure(url+log4j.xml);
} catch(Exception e) {
e.printStackTrace();
}
And I would expect a FileNotFoundException if the log4j.xml doesn't exist, and then the catch-block would be executed.
But I don't see an exception when the file doesn't exist, why is that?
If you look at the source of DOMConfigurator.doConfigure it looks like it catches Exception and then just logs the error rather than rethrowing it. Therefore the FileNotFoundException will not make it back to your calling code.
try {
...
} catch (Exception e) {
if (e instanceof InterruptedException || e instanceof InterruptedIOException) {
Thread.currentThread().interrupt();
}
// I know this is miserable...
LogLog.error("Could not parse "+ action.toString() + ".", e);
}
To work around this you could preemptively check if the file exists yourself.
Try catching a Throwable instead of an Exception and do a print stack trace. That way you can catch any errors or exceptions and change your code accordingly.
In case you want to disable those messages from log4j, you can set log4j in quiet mode:
LogLog.setQuietMode(true);
I have a method that looks like this:
try {
doStuff();
} catch (Exception ex) {
logger.error(ex);
}
(I don't really use method names like doStuff - this is just to make things easy)
In doStuff I do a variety of things, among them is call a data access method (so, another method within doStuff) that ends with the following:
} catch (SQLException ex) {
logger.error(ex);
} finally {
try {
connection.close();
proc.close();
results.close();
} catch (Exception e) {
logger.error(e);
} //<--Exception thrown here. HUH?
}
return stuff;
When stepping through this code I get to the second to last curly brace (marked with a comment) and then jump up to the catch in the first code block with a NullPointer exception. The results.close() is what is being run right before it (results is not null). My IDE (NetBeans) doesn't provide a stack trace (it shows the stack trace is null) or any other information other than the name of the exception (from what I can tell).
This code was running fine previously. In fact while it was running, I changed the stored procedure that the data access method (where I'm getting this exception) was calling, and then this error started to occur (without the application having been stopped at all). I've since tried rebuilding and restarting but to no avail. I could change the sproc back but I really want to find out what this error is from since it makes no sense that the sproc would even be a part of this considering where in the code the exception is occurring.
your doStuff() method is throwing something other than a SQLException and it is not being caught. add a catch(Exception e) block and log that exception and see what happens.
this code sample exhibits the same behaviour you are describing:
public class TryCatchTest {
public static void main(String[] args) {
try {
System.out.println("foo");
throw new NullPointerException();
} finally {
try {
System.out.println("bar");
} catch (Exception e) {
e.printStackTrace();
}
} // exception thrown here
}
}
Close the resources in the reverse order in which they were obtained:
try
{
results.close();
proc.close();
connection.close();
}
catch (Exception e)
{
logger.error(e);
} //<--Exception thrown here. HUH?
I'd also recommend methods like these:
public class DatabaseUtils
{
// similar for ResultSet and Statement
public static void close(Connection c)
{
try
{
if (c != null)
{
c.close();
}
}
catch (SQLException e)
{
// log or print.
}
}
}
It could well be that logger is null.
Hard-to-pinpoint exceptions are often thrown in the exception handler itself.
NullPointerException can not be thrown in a line without a statement.
Check that the class file you are executing is of the same version as the source you view (I have had similar issues when an incorrectly configured classpath contained a class twice and the older version was found first in the classpath, or a recompiled class files for not correctly copied to the web container I used for testing).
Edit: As emh points out, it could also be that exception occured prior to entering the finally block.
I'm 99% sure this is happening in the JDBC driver. For starters, your close statements are backwards. You should close the resultset, the statement and the connection, in that order.
If you are running in an application server which is managing the transactions, then the attempt to commit the transaction may trigger the exception inside the JDBC driver.
It could also be something about how result sets are generated in the stored proceedure, such as accessing one, then accessing another, and then referring back to the first one.
As I said in a comment, never catch an exception that you don't want to deal with. In your code, assuming that it is complete, you are not doing anything interesting with the exception, and it is causing you confusion on where and why the exception is happening. If you really want to do more than log or printStackTrace(), like wrapping it with a domain-specific exception (like your.package.DataAccessException or something), then great.
Do something more like this:
ResultSet results = null;
CallableStatement proc = null;
Connection connection = null;
try {
connection = >
proc = connection.createCallableStatement(..);
results = proc.execute(..);
>
} finally {
try {
if ( results != null ) {
results.close();
}
} catch (Exception e) {
logger.error(e);
}
try {
if ( proc != null ) {
proc.close();
}
} catch (Exception e) {
logger.error(e);
}
try {
if ( connection != null ) {
connection.close();
}
} catch (Exception e) {
logger.error(e);
}
}
And then in the caller:
try {
doStuff();
} catch ( SQLException e ) {
throw new your.package.DataAccessException(e);
// or just let the SQLException propagate upward
} catch ( Exception e ) {
throw new your.package.AppException("omg, crazy pills!", e);
// or, once again, just let the exception
// propagate and don't catch anything
}
So, take-away:
don't log exception where they happen, just pass them on, nested in another exception. You don't want your process to not know whether or not the SQL action succeeded or not. You would rather stop and do something else.
Nest exceptions until the get to the end of the line, that way, you always have the complete trace in the place that you wanted to deal with the exception, not in five places scattered throughout your server log.
Nest exceptions (yes, I said that twice!) so that you don't care where the JVM actually throws the exception from, you have the next exception to follow, telling you it was actually a callable statement, or improper closing of your resources, etc.
Don't nest and throw exceptions from errors caught in your finally code, that will interfere with the original exception and that will be more interesting than the failure to close and statement that didn't get opened in the first place.
Set variables to null before you use them, and then check for null before close()ing them.
Catch each problem in the finally block individually, as you might not be able to close your ResultSet (because some execution error caused it not to open in the first place), but you should still try to close the CallableStatement and Connection, as it is probably unaffected and will still cause you to leak resources.
Hope that helps.
Is there an elegant way to handle exceptions that are thrown in finally block?
For example:
try {
// Use the resource.
}
catch( Exception ex ) {
// Problem with the resource.
}
finally {
try{
resource.close();
}
catch( Exception ex ) {
// Could not close the resource?
}
}
How do you avoid the try/catch in the finally block?
I usually do it like this:
try {
// Use the resource.
} catch( Exception ex ) {
// Problem with the resource.
} finally {
// Put away the resource.
closeQuietly( resource );
}
Elsewhere:
protected void closeQuietly( Resource resource ) {
try {
if (resource != null) {
resource.close();
}
} catch( Exception ex ) {
log( "Exception during Resource.close()", ex );
}
}
I typically use one of the closeQuietly methods in org.apache.commons.io.IOUtils:
public static void closeQuietly(OutputStream output) {
try {
if (output != null) {
output.close();
}
} catch (IOException ioe) {
// ignore
}
}
If you're using Java 7, and resource implements AutoClosable, you can do this (using InputStream as an example):
try (InputStream resource = getInputStream()) {
// Use the resource.
}
catch( Exception ex ) {
// Problem with the resource.
}
Arguably a bit over the top, but maybe useful if you're letting exceptions bubble up and you can't log anything from within your method (e.g. because it's a library and you'd rather let the calling code handle exceptions and logging):
Resource resource = null;
boolean isSuccess = false;
try {
resource = Resource.create();
resource.use();
// Following line will only run if nothing above threw an exception.
isSuccess = true;
} finally {
if (resource != null) {
if (isSuccess) {
// let close throw the exception so it isn't swallowed.
resource.close();
} else {
try {
resource.close();
} catch (ResourceException ignore) {
// Just swallow this one because you don't want it
// to replace the one that came first (thrown above).
}
}
}
}
UPDATE: I looked into this a bit more and found a great blog post from someone who has clearly thought about this more than me: http://illegalargumentexception.blogspot.com/2008/10/java-how-not-to-make-mess-of-stream.html He goes one step further and combines the two exceptions into one, which I could see being useful in some cases.
As of Java 7 you no longer need to explicitly close resources in a finally block instead you can use try-with-resources syntax. The try-with-resources statement is a try statement that declares one or more resources. A resource is an object that must be closed after the program is finished with it. The try-with-resources statement ensures that each resource is closed at the end of the statement. Any object that implements java.lang.AutoCloseable, which includes all objects which implement java.io.Closeable, can be used as a resource.
Assume the following code:
try( Connection con = null;
Statement stmt = con.createStatement();
Result rs= stmt.executeQuery(QUERY);)
{
count = rs.getInt(1);
}
If any exception happens the close method will be called on each of these three resources in opposite order in which they were created. It means the close method would be called first for ResultSetm then the Statement and at the end for the Connection object.
It's also important to know that any exceptions that occur when the close methods is automatically called are suppressed. These suppressed exceptions can be retrieved by getsuppressed() method defined in the Throwable class.
Source: https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
Ignoring exceptions which occur in a 'finally' block is generally a bad idea unless one knows what those exceptions will be and what conditions they will represent. In the normal try/finally usage pattern, the try block places things into a state the outside code won't be expecting, and the finally block restores those things' state to what the outside code expects. Outside code which catches an exception will generally expect that, despite the exception, everything has been restored to a normal state. For example, suppose some code starts a transaction and then tries to add two records; the "finally" block performs a "rollback if not committed" operation. A caller might be prepared for an exception to occur during the execution of the second "add" operation, and may expect that if it catches such an exception, the database will be in the state it was before either operation was attempted. If, however, a second exception occurs during the rollback, bad things could happen if the caller makes any assumptions about the database state. The rollback failure represents a major crisis--one which should not be caught by code expecting a mere "Failed to add record" exception.
My personal inclination would be to have a finally method catch exceptions that occur and wrap them in a "CleanupFailedException", recognizing that such failure represents a major problem and such an exception should not be caught lightly.
One solution, if the two Exceptions are two different classes
try {
...
}
catch(package1.Exception err)
{
...
}
catch(package2.Exception err)
{
...
}
finally
{
}
But sometimes you cannot avoid this second try-catch. e.g. for closing a stream
InputStream in=null;
try
{
in= new FileInputStream("File.txt");
(..)// do something that might throw an exception during the analysis of the file, e.g. a SQL error
}
catch(SQLException err)
{
//handle exception
}
finally
{
//at the end, we close the file
if(in!=null) try { in.close();} catch(IOException err) { /* ignore */ }
}
Why do you want to avoid the additional block? Since the finally block contains "normal" operations which may throw an exception AND you want the finally block to run completely you HAVE to catch exceptions.
If you don't expect the finally block to throw an exception and you don't know how to handle the exception anyway (you would just dump stack trace) let the exception bubble up the call stack (remove the try-catch from the finally block).
If you want to reduce typing you could implement a "global" outer try-catch block, which will catch all exceptions thrown in finally blocks:
try {
try {
...
} catch (Exception ex) {
...
} finally {
...
}
try {
...
} catch (Exception ex) {
...
} finally {
...
}
try {
...
} catch (Exception ex) {
...
} finally {
...
}
} catch (Exception ex) {
...
}
After lots of consideration, I find the following code best:
MyResource resource = null;
try {
resource = new MyResource();
resource.doSomethingFancy();
resource.close();
resource = null;
} finally {
closeQuietly(resource)
}
void closeQuietly(MyResource a) {
if (a!=null)
try {
a.close();
} catch (Exception e) {
//ignore
}
}
That code guarantees following:
The resource is freed when the code finished
Exceptions thrown when closing the resource are not consumed without processing them.
The code does not try to close the resource twice, no unnecessary exception will be created.
If you can you should test to avoid the error condition to begin with.
try{...}
catch(NullArgumentException nae){...}
finally
{
//or if resource had some useful function that tells you its open use that
if (resource != null)
{
resource.Close();
resource = null;//just to be explicit about it was closed
}
}
Also you should probably only be catching exceptions that you can recover from, if you can't recover then let it propagate to the top level of your program. If you can't test for an error condition that you will have to surround your code with a try catch block like you already have done (although I would recommend still catching specific, expected errors).
You could refactor this into another method ...
public void RealDoSuff()
{
try
{ DoStuff(); }
catch
{ // resource.close failed or something really weird is going on
// like an OutOfMemoryException
}
}
private void DoStuff()
{
try
{}
catch
{
}
finally
{
if (resource != null)
{
resource.close();
}
}
}
I usually do this:
MyResource r = null;
try {
// use resource
} finally {
if( r != null ) try {
r.close();
} catch( ThatSpecificExceptionOnClose teoc ){}
}
Rationale: If I'm done with the resource and the only problem I have is closing it, there is not much I can do about it. It doesn't make sense either to kill the whole thread if I'm done with the resource anyway.
This is one of the cases when at least for me, it is safe to ignore that checked exception.
To this day I haven't had any problem using this idiom.
try {
final Resource resource = acquire();
try {
use(resource);
} finally {
resource.release();
}
} catch (ResourceException exx) {
... sensible code ...
}
Job done. No null tests. Single catch, include acquire and release exceptions. Of course you can use the Execute Around idiom and only have to write it once for each resource type.
Changing Resource from best answer to Closeable
Streams implements Closeable Thus you can reuse the method for all streams
protected void closeQuietly(Closeable resource) {
if (resource == null)
return;
try {
resource.close();
} catch (IOException e) {
//log the exception
}
}
I encountered a situation similar where I couldn't use try with resources but I also wanted to handle the exception coming from the close, not just log and ignore it like closeQuietly mechanism do. in my case I'm not actually dealing with an output stream, so the failure on close is of more interest than a simple stream.
IOException ioException = null;
try {
outputStream.write("Something");
outputStream.flush();
} catch (IOException e) {
throw new ExportException("Unable to write to response stream", e);
}
finally {
try {
outputStream.close();
} catch (IOException e) {
ioException = e;
}
}
if (ioException != null) {
throw new ExportException("Unable to close outputstream", ioException);
}