Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #37121

Re: Is this the way to work with try with resources

From Arne Vajhøj <arne@vajhoej.dk>
Newsgroups comp.lang.java.programmer
Subject Re: Is this the way to work with try with resources
Date 2017-08-09 20:53 -0400
Organization Aioe.org NNTP Server
Message-ID <omgapf$dlf$1@gioia.aioe.org> (permalink)
References <87poc6wb9n.fsf@munus.decebal.nl> <omdob4$cif$1@gioia.aioe.org> <omdovg$d4o$1@gioia.aioe.org> <87k22dux5g.fsf@munus.decebal.nl>

Show all headers | View raw


On 8/9/2017 1:29 AM, Cecil Westerhof wrote:
> I now have:
>          try (ResultSet rsTotal  = conn.createStatement().executeQuery(COUNT_TOTAL_PROV);
>               ResultSet rsUnused = conn.createStatement().executeQuery(COUNT_UNUSED_PROV);
>               ResultSet rsUsed   = conn.createStatement().executeQuery(COUNT_USED_PROV)) {
> 
> That could go wrong?

Lots.

See previous posts.

>                   If so: is there a way to verify if it goes OK, or
> wrong?

Interesting question.

There are probably many approaches.

But here is one.

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class DBCode {
     public static void main(String[] args) throws SQLException {
         Connection con = 
DriverManager.getConnection("jdbc:mysql://localhost/Test", "root", "");
         con = Reveal.wrap(con); // <----
         Statement stmt = con.createStatement();
         ResultSet rs = stmt.executeQuery("SELECT f1,f2 fROM t1");
         while(rs.next()) {
             System.out.printf("%d %s\n",  rs.getInt(1), rs.getString(2));
         }
         //rs.close();
         //stmt.close();
         PreparedStatement pstmt = con.prepareStatement("SELECT f1,f2 
fROM t1 WHERE f1 > ?");
         pstmt.setInt(1, 2);
         ResultSet prs = pstmt.executeQuery();
         while(prs.next()) {
             System.out.printf("%d %s\n",  prs.getInt(1), prs.getString(2));
         }
         //prs.close();
         //pstmt.close();
         //con.close();
         Reveal.dumpOpen(System.out); // <----
     }
}

Output:

Unclosed: Connection#1
Unclosed: ResultSet#2 from PreparedStatement#1 (SELECT f1,f2 fROM t1 
WHERE f1 > ?) from Connection#1
Unclosed: Statement#1 from Connection#1
Unclosed: PreparedStatement#1 (SELECT f1,f2 fROM t1 WHERE f1 > ?) from 
Connection#1
Unclosed: ResultSet#1 (SELECT f1,f2 fROM t1) from Statement#1 from 
Connection#1

The "magic" sauce:

import java.io.PrintStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashSet;
import java.util.Set;

public class Reveal {
     public static interface TrackableResource {
         public String getId() throws SQLException;
     }
     private static Set<TrackableResource> reslst = new 
HashSet<TrackableResource>();
     public static class ResultSetWrapper implements InvocationHandler, 
TrackableResource {
         private static int count = 0;
         private int num;
         private ResultSet rs;
         private String parent;
         private String sql;
         public ResultSetWrapper(ResultSet rs, String parent) {
             this.rs = rs;
             this.parent = parent;
             this.sql = null;
             synchronized(reslst) {
                 count++;
                 num = count;
                 reslst.add(this);
             }
         }
         public ResultSetWrapper(ResultSet rs, String parent, String sql) {
             this.rs = rs;
             this.parent = parent;
             this.sql = sql;
             synchronized(reslst) {
                 count++;
                 num = count;
                 reslst.add(this);
             }
         }
         public Object invoke(Object proxy, Method method, Object[] 
args) throws Throwable {
             if(method.getName().equals("close")) {
                 reslst.remove(this);
                 return method.invoke(rs, args);
             } else {
                 return method.invoke(rs, args);
             }
         }
         public String getId() throws SQLException {
             if(sql == null) {
                 return "ResultSet#" + num + " from " + parent;
             } else {
                 return "ResultSet#" + num + " (" + sql + ") from " + 
parent;
             }
         }
     }
     public static class PreparedStatementWrapper implements 
InvocationHandler, TrackableResource {
         private static int count = 0;
         private int num;
         private Statement stmt;
         private String parent;
         private String sql;
         public PreparedStatementWrapper(Statement stmt, String parent, 
String sql) {
             this.stmt = stmt;
             this.parent = parent;
             this.sql = sql;
             synchronized(reslst) {
                 count++;
                 num = count;
                 reslst.add(this);
             }
         }
         public Object invoke(Object proxy, Method method, Object[] 
args) throws Throwable {
             if(method.getName().equals("close")) {
                 reslst.remove(this);
                 return method.invoke(stmt, args);
             } else if(method.getName().equals("executeQuery")) {
                 return 
(ResultSet)Proxy.newProxyInstance(getClass().getClassLoader(), new 
Class<?>[] { ResultSet.class },
                                                          new 
ResultSetWrapper((ResultSet)method.invoke(stmt, args), getId()));
             } else {
                 return method.invoke(stmt, args);
             }
         }
         public String getId() throws SQLException {
             return "PreparedStatement#" + num + " (" + sql + ") from " 
+ parent;
         }
     }
     public static class StatementWrapper implements InvocationHandler, 
TrackableResource {
         private static int count = 0;
         private int num;
         private Statement stmt;
         private String parent;
         public StatementWrapper(Statement stmt, String parent) {
             this.stmt = stmt;
             this.parent = parent;
             synchronized(reslst) {
                 count++;
                 num = count;
                 reslst.add(this);
             }
         }
         public Object invoke(Object proxy, Method method, Object[] 
args) throws Throwable {
             if(method.getName().equals("close")) {
                 reslst.remove(this);
                 return method.invoke(stmt, args);
             } else if(method.getName().equals("executeQuery")) {
                 return 
(ResultSet)Proxy.newProxyInstance(getClass().getClassLoader(), new 
Class<?>[] { ResultSet.class },
                                                          new 
ResultSetWrapper((ResultSet)method.invoke(stmt, args), getId(), 
(String)args[0]));
             } else {
                 return method.invoke(stmt, args);
             }
         }
         public String getId() throws SQLException {
             return "Statement#" + num + " from " + parent;
         }
     }
     public static class ConnectionWrapper implements InvocationHandler, 
TrackableResource {
         private static int count = 0;
         private int num;
         private Connection con;
         public ConnectionWrapper(Connection con) {
             this.con = con;
             synchronized(reslst) {
                 count++;
                 num = count;
                 reslst.add(this);
             }
         }
         public Object invoke(Object proxy, Method method, Object[] 
args) throws Throwable {
             if(method.getName().equals("close")) {
                 reslst.remove(this);
                 return method.invoke(con, args);
             } else if(method.getName().equals("createStatement")) {
                 return 
(Statement)Proxy.newProxyInstance(con.getClass().getClassLoader(), new 
Class<?>[] { Statement.class },
                                                          new 
StatementWrapper((Statement)method.invoke(con, args), getId()));
             } else if(method.getName().equals("prepareStatement")) {
                 return 
(PreparedStatement)Proxy.newProxyInstance(con.getClass().getClassLoader(), 
new Class<?>[] { PreparedStatement.class },
                                                                  new 
PreparedStatementWrapper((PreparedStatement)method.invoke(con, args), 
getId(), (String)args[0]));
             } else {
                 return method.invoke(con, args);
             }
         }
         public String getId() throws SQLException {
             return "Connection#" + num;
         }
     }
     public static Connection wrap(Connection con) {
         return 
(Connection)Proxy.newProxyInstance(con.getClass().getClassLoader(), new 
Class<?>[] { Connection.class },
                                                   new 
ConnectionWrapper(con));
     }
     public static void dumpOpen(PrintStream ps) throws SQLException {
         for(TrackableResource obj : reslst.toArray(new 
TrackableResource[0])) {
             System.out.println("Unclosed: " + obj.getId());
         }
     }
}

Arne

Back to comp.lang.java.programmer | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

Is this the way to work with try with resources Cecil Westerhof <Cecil@decebal.nl> - 2017-08-08 13:26 +0200
  Re: Is this the way to work with try with resources Martin Gregorie <martin@address-in-sig.invalid> - 2017-08-08 12:51 +0000
    Re: Is this the way to work with try with resources Cecil Westerhof <Cecil@decebal.nl> - 2017-08-09 07:10 +0200
  Re: Is this the way to work with try with resources Patrick Roemer <sangamon@netcologne.de> - 2017-08-08 18:29 +0200
    Re: Is this the way to work with try with resources Cecil Westerhof <Cecil@decebal.nl> - 2017-08-09 07:20 +0200
    Re: Is this the way to work with try with resources Cecil Westerhof <Cecil@decebal.nl> - 2017-08-09 07:16 +0200
  Re: Is this the way to work with try with resources Patrick Roemer <sangamon@netcologne.de> - 2017-08-08 19:30 +0200
    Re: Is this the way to work with try with resources Cecil Westerhof <Cecil@decebal.nl> - 2017-08-09 06:49 +0200
    Re: Is this the way to work with try with resources Cecil Westerhof <Cecil@decebal.nl> - 2017-08-09 07:01 +0200
    Re: Is this the way to work with try with resources Patrick Roemer <sangamon@netcologne.de> - 2017-08-09 15:39 +0200
  Re: Is this the way to work with try with resources Arne Vajhøj <arne@vajhoej.dk> - 2017-08-08 21:25 -0400
    Re: Is this the way to work with try with resources Arne Vajhøj <arne@vajhoej.dk> - 2017-08-08 21:36 -0400
      Re: Is this the way to work with try with resources Cecil Westerhof <Cecil@decebal.nl> - 2017-08-09 07:29 +0200
        Re: Is this the way to work with try with resources Arne Vajhøj <arne@vajhoej.dk> - 2017-08-09 20:53 -0400
          Re: Is this the way to work with try with resources Arne Vajhøj <arne@vajhoej.dk> - 2017-08-09 23:03 -0400
    Re: Is this the way to work with try with resources Arne Vajhøj <arne@vajhoej.dk> - 2017-08-08 21:48 -0400
    Re: Is this the way to work with try with resources Cecil Westerhof <Cecil@decebal.nl> - 2017-08-09 07:24 +0200
  Re: Is this the way to work with try with resources Cecil Westerhof <Cecil@decebal.nl> - 2017-08-09 06:26 +0200
    Re: Is this the way to work with try with resources Cecil Westerhof <Cecil@decebal.nl> - 2017-08-09 08:30 +0200
    Re: Is this the way to work with try with resources Andreas Leitgeb <avl@logic.at> - 2017-08-09 09:40 +0000
      Re: Is this the way to work with try with resources Cecil Westerhof <Cecil@decebal.nl> - 2017-08-09 12:56 +0200
        Re: Is this the way to work with try with resources Andreas Leitgeb <avl@logic.at> - 2017-08-09 16:51 +0000
          Re: Is this the way to work with try with resources Cecil Westerhof <Cecil@decebal.nl> - 2017-08-09 19:37 +0200
            Re: Is this the way to work with try with resources Andreas Leitgeb <avl@logic.at> - 2017-08-09 19:51 +0000
              Re: Is this the way to work with try with resources Cecil Westerhof <Cecil@decebal.nl> - 2017-08-09 22:20 +0200
                Re: Is this the way to work with try with resources Cecil Westerhof <Cecil@decebal.nl> - 2017-08-09 23:17 +0200
          Re: Is this the way to work with try with resources Patrick Roemer <sangamon@netcologne.de> - 2017-08-09 22:08 +0200
        Re: Is this the way to work with try with resources Arne Vajhøj <arne@vajhoej.dk> - 2017-08-09 18:07 -0400
    Re: Is this the way to work with try with resources Arne Vajhøj <arne@vajhoej.dk> - 2017-08-09 18:05 -0400
  Re: Is this the way to work with try with resources Cecil Westerhof <Cecil@decebal.nl> - 2017-08-09 06:39 +0200

csiph-web