0


Recently I was looking at the frequent hangs of the tomcat server and came across some exceptions thrown frequently in some part of the code.

When I examined the code, this what it looked like

public static String doSomething() {
    String returnVakue = "default value";

    try {
        ResultSet rs = getMyResultSet(); 

        rs.first(); 
        returnValue = rs.getString("my_field"); // Note that Exception happens at times when the ResultSet is empty

    } catch (Exception e) {
        throw new Exception(e);
    } finally {
        return returnValue;
    }

}

While I am aware that it is perfectly OK to have both throws exception and return, wondering if this can cause any kind of leaks in tomcat. And Is there any potential risk with performance. ? Hoowever my caller function stops the execution at this point. Any views on this? Does it affect the GC?

EDIT : NOTE : I Know how to correct this code. Please share your views whether this can potentially cause tomcat hanging.

Akhil
  • 2,602
  • 23
  • 36
  • Additional information : Tomcat starts behaving slow after multiple instance of this case – Akhil Aug 19 '13 at 20:16
  • "While I am aware that it is perfectly OK to have both throws exception and return" - This makes no sense. If you throw an exception, the calling method is never going to see it anyway, as it's going to go into exception-handling mode and not use the returned value anyway. Would strongly encourage you to remove the finally block from that code and see if your problems go away. – StormeHawke Aug 19 '13 at 20:21
  • Thanks for the comment. But what I meant is that Syntactically Java supports that. I am very much clear that the this is senseless programming. I will correct it . But my problem is that whether this is the one causing tomcat to hang after a while. – Akhil Aug 19 '13 at 20:24
  • 2
    @StormeHawke There will be no exception thrown here, the method will return the returnValue, and the exception is discarded. – nos Aug 19 '13 at 20:27
  • 1
    @Akhil Is this the actual, and whole code ? It doesn't close() the ResultSet, an possibly not the JDBC connection either. This will pile up and you'll eventually run out of memory or slow down your database. – nos Aug 19 '13 at 20:28
  • 1
    @nos Yes, I have checked for that. My connection management is handled in a different layer and that layer takes care of that all JDBC related resources. This is a pseudo code ..Not the actual. – Akhil Aug 19 '13 at 20:30
  • @nos - `throw new Exception(e);` Returning some value after catching and then throwing an exception is entirely possible with this code. What that returned value will be would be hard to define. – StormeHawke Aug 19 '13 at 20:36
  • @StormeHawke The return statement is in a finally {} block, so the finally block will be run, and it will return, regardless of throwing a exception. The returned value is either the string "default value", or the return value from the rs.getString("my_field") – nos Aug 19 '13 at 20:38
  • @nos That's my point. It'll be returned, but to where? Will the value be assigned in the caller, or not? Since the exception has already been thrown, will java even know where in the stack to return the value? Seems to me this could result in some mighty strange behavior – StormeHawke Aug 19 '13 at 20:44
  • 1
    @StormeHawke Exactly.. thats the point I am trying to bring up. Can anyone clearly define what will happen in such cases. Can this push tomcat to an indefinite state? – Akhil Aug 19 '13 at 20:46
  • 1
    @StormeHawke As mentioned, the exception is swallowed. The function will return normally. It will be assigned to the caller. This is well defined. See e.g. http://stackoverflow.com/questions/5126455/in-java-what-if-both-try-and-catch-throw-same-exception-and-finally-has-a-return – nos Aug 20 '13 at 07:01

2 Answers2

0

First check if returned ResultSet is empty.

while( rs.next() ) {
    // ResultSet processing here
    // Result set is not empty
}

In my opinion throwing exception is your decision, but in finally you should be doing clean up e.g. closing Connections.

Open Connections if not closed will cause tomcat to hang because new requests coming to server will be waiting for connections to become available.

Any object in Java which is referenced is not garabage collected, in your case if Connections are not closing then these objects will not be garbage collected.

Cheers !!

Sachin Thapa
  • 3,559
  • 4
  • 24
  • 42
0

If a query takes a long time, not a question of JDBC. The database is responsible. Of course, if JDBC is used properly. In another hand, if you use simple JDBC, it is best that you add a layer DAO in your application.

public class UserDAO extends DAO {

    private static final String FIND_BY_PK_SQL = 
        "SELECT mail, password " +
        "  FROM user WHERE mail = ?";

    public User findByPk(final String mail) throws DAOException {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            conn = getConnection();
            ps = conn.prepareStatement(FIND_BY_PK_SQL);
            ps.setString(1, mail);
            rs = ps.executeQuery();
            if (rs.next()) {
                return fill(rs);
            }
            return null;
        } catch (final SQLException e) {
            throw new DAOException(e);
        } finally {
            DbUtils.closeQuietly(conn, ps, rs);
        }
    }

    private User fill(final ResultSet rs) throws SQLException {
        final User user = new User();
        user.setMail(rs.getString("mail"));
        user.setPassword(rs.getString("password"));
        return user;
    }
}
Paul Vargas
  • 41,222
  • 15
  • 102
  • 148