More Finally

R

RedGrittyBrick

Given this code ...

String driver = "jdbc:myDriver:wombat";
String id = "myLogin";
String pw = "myPassword";
String sql = "select name, phone from contact";

Connection connection = DriverManager.getConnection(driver, id, pw);
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(sql);
while (resultSet.next()) {
String name = resultSet.getString(1);
String phone = resultSet.getString(2);
System.out.println(name + ": " + phone);
}
resultSet.close();
statement.close();
connection.close();

All statements after the first four can throw SQLException, three lots
of resources are potentially allocated (connection, statement and
resultSet).

Sun's examples[1] put those statements into a single try block with no
finally clause and don't really attempt to release local or server
resources.

So far as I can see, to have the resource releasing code in a finally
block would require at three nested try/catch/finally structures - one
for each resource we want to close if it is open.

Assuming that the other parts of this application can usefully continue
if this particular function fails, what is the best way to use
try/catch/finally?
 
P

Patricia Shanahan

RedGrittyBrick said:
Given this code ...

String driver = "jdbc:myDriver:wombat";
String id = "myLogin";
String pw = "myPassword";
String sql = "select name, phone from contact";

Connection connection = DriverManager.getConnection(driver, id, pw);
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(sql);
while (resultSet.next()) {
String name = resultSet.getString(1);
String phone = resultSet.getString(2);
System.out.println(name + ": " + phone);
}
resultSet.close();
statement.close();
connection.close();

All statements after the first four can throw SQLException, three lots
of resources are potentially allocated (connection, statement and
resultSet).

Sun's examples[1] put those statements into a single try block with no
finally clause and don't really attempt to release local or server
resources.

So far as I can see, to have the resource releasing code in a finally
block would require at three nested try/catch/finally structures - one
for each resource we want to close if it is open.

Assuming that the other parts of this application can usefully continue
if this particular function fails, what is the best way to use
try/catch/finally?

There is an alternative approach in which each variable is declared
outside a single try-catch-finally, with initial value null. In the
finally block there are multiple pieces of code of the form:

if(something != null){
// clean up something
}

Patricia
 
M

Mark Rafn

Given this code ...
Connection connection = DriverManager.getConnection(driver, id, pw);
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(sql);
while (resultSet.next()) {
String name = resultSet.getString(1);
String phone = resultSet.getString(2);
System.out.println(name + ": " + phone);
}
resultSet.close();
statement.close();
connection.close();
Sun's examples[1] put those statements into a single try block with no
finally clause and don't really attempt to release local or server
resources.

In the dirt-simple, example case, resources are released when the object is
garbage collected. In almost any real code, that's not good enough.
So far as I can see, to have the resource releasing code in a finally
block would require at three nested try/catch/finally structures - one
for each resource we want to close if it is open.

The pattern I normally see is:
Connecton connection = null;
try {
connection = Something.getConnection();
... do work ...
} finally {
if (connection != null) try { connection.close(); }
catch (SQLException ignore) { }
}

AFAIK, closing the connection closes all resources opened through that
connection, including resources used by Statement and ResultSet objects.

If you wanted to use the Connection for multiple Statements, and be sure to
close each of them between uses, you'd need to nest try/finally.
 
M

Mike Schilling

Patricia Shanahan said:
RedGrittyBrick said:
Given this code ...

String driver = "jdbc:myDriver:wombat";
String id = "myLogin";
String pw = "myPassword";
String sql = "select name, phone from contact";

Connection connection = DriverManager.getConnection(driver, id, pw);
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(sql);
while (resultSet.next()) {
String name = resultSet.getString(1);
String phone = resultSet.getString(2);
System.out.println(name + ": " + phone);
}
resultSet.close();
statement.close();
connection.close();

All statements after the first four can throw SQLException, three lots of
resources are potentially allocated (connection, statement and
resultSet).

Sun's examples[1] put those statements into a single try block with no
finally clause and don't really attempt to release local or server
resources.

So far as I can see, to have the resource releasing code in a finally
block would require at three nested try/catch/finally structures - one
for each resource we want to close if it is open.

Assuming that the other parts of this application can usefully continue
if this particular function fails, what is the best way to use
try/catch/finally?

There is an alternative approach in which each variable is declared
outside a single try-catch-finally, with initial value null. In the
finally block there are multiple pieces of code of the form:

if(something != null){
// clean up something
}

Unfortunately, each close method can also throw an exception, so there's no
guarantee they're all called. How to structure this depends on how an
exception thrown from close() should be handled (e.g. ignored, caught and
logged, or rethrown)
 
L

Lew

Mike said:
Unfortunately, each close method can also throw an exception, so there's no
guarantee they're all called. How to structure this depends on how an
exception thrown from close() should be handled (e.g. ignored, caught and
logged, or rethrown)

You can wrap the close() methods in a utility class method, e.g.,

public class Util
{
public static void close( Connection c )
{
try
{
c.close();
}
catch ( SQLException e )
{
logger.warn( "Cannot close Connection: \""
+ e.getSQLState() +"\". "+ e );
}
}
}

(This represents a log-and-ignore strategy.)

Then you use the utility methods in your finally{} cleanup block confident
that your close() Exceptions are handled.
 
T

Thomas Hawtin

Patricia said:
RedGrittyBrick said:
Sun's examples[1] put those statements into a single try block with no
finally clause and don't really attempt to release local or server
resources.

There is much bad example code.

Three try/finally and a try/catch. In real code one wouldn't actually
write code that ranges from accessing the DriverManager to ResultSet
data. One can, of course, use the execute-around idiom to factor out the
repeated code.
There is an alternative approach in which each variable is declared
outside a single try-catch-finally, with initial value null. In the
finally block there are multiple pieces of code of the form:

That is really ugly. As well as introducing unnecessary code, it
obscures the range of code that the finally clears up after. As pointed
out by someone else, one also have to be very careful about exceptions
in finally.

Tom Hawtin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,818
Latest member
Brigette36

Latest Threads

Top