Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-5086403

Generated connection object is unreferenced in one JdbcRowSetImpl constructor

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P4 P4
    • 6
    • 5.0
    • core-libs
    • b91
    • x86
    • windows_xp
    • Verified

      Name: rmT116609 Date: 08/12/2004


      FULL PRODUCT VERSION :
      java version "1.5.0-beta2"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-beta2-b51)
      Java HotSpot(TM) Client VM (build 1.5.0-beta2-b51, mixed mode, sharing)

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows XP [Version 5.1.2600]

      A DESCRIPTION OF THE PROBLEM :
      Sun JDK 5.0-beta2 RowSet implementation class com.sun.rowset.JdbcRowSetImpl has three constructors. The following constructor invokes connect() method to obtain a java.sql.Connection object instance, but the generated object instance is unreferenced:

      public JdbcRowSetImpl(String s, String s1, String s2) throws SQLException {
      ...
      connect();
      ...
      }

      Since this connection object is unreferenced, the garbage collector will run and the finalizer thread will be started to run. The other 2 constructors don't have this issue.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Write code that uses a JDBC driver to utilize RowSet, create a JdbcRowSetImpl with url, username, and password as parameters using the following constructor:

      public JdbcRowSetImpl(String s, String s1, String s2) throws SQLException

      and try to load the rowset.

      For example:

      public static void main (String args[]) {
         String url="jdbc:teradata://DatabaseName/TMODE=ANSI,LOG=DEBUG";
         String user = "username";
         String password = "password";
         String tableName = "RowSetImplTest";
         String sqlCreate = "CREATE TABLE " + tableName + "(c1 NOT NULL PRIMARY KEY integer)";
         String sqlSelect = "SELECT * FROM " + tableName + " order by c1";
         String sqlDrop = "DROP TABLE " + tableName ;
         int max = 3;

         try {
            // Initialize Connection and JdbcRowSet
            Class.forName ("com.ncr.teradata.TeraDriver");
            Connection con = DriverManager.getConnection (url, user, password) ;
            try {
               try {
      execSQL(con, sqlDrop);
               }
               catch (SQLException ex) {
      System.out.println ("Ignoring drop-table exception: " + ex);
               }
               try {
      execSQL(con, sqlCreate);
               }
               catch (SQLException ex) {
      System.out.println ("Exception during table creation: " + ex);
               }
               try {
      System.out.println ("Creating JdbcRowSet...");
      // Initialize test data
      Random rand = new Random(0);
      int[] value = new int[max];
      for (int i = 0; i < max; i++) {
      value[i] = rand.nextInt(); System.out.println ("" + value[i]);
      }
      Arrays.sort(value);
      // Insert test data into table
      PreparedStatement ps = con.prepareStatement("INSERT INTO " + tableName + " (?);");
      for (int i = 0; i < max; i++) {
      ps.setInt(1, value[i]);
      ps.executeUpdate();
      }
      ps.close();

                      Class cls = Class.forName("com.sun.rowset.JdbcRowSetImpl");
      Constructor cn = cls.getConstructor(new Class[] { String.class, String.class, String.class });
      RowSet jrs = (RowSet)cn.newInstance(new Object[] { url, user, password }); jrs.setCommand(sqlSelect);
      jrs.execute();
      System.out.println ("Output the test data: ");
      for (int i = 0; i < max; i++) {
      jrs.next();
      int value2 = jrs.getInt(1);
      System.out.println ("" + value2);
      if (value[i] != value2) {
      System.out.println ("Error: returned value != inserted value !");
      }
      }

      if (jrs != null)
      jrs.close();
               }
               finally {
      execSQL(con, sqlDrop);
               }
            }
            finally {
      con.close ();
            }
         }
         catch (Exception ex) {
      ex.printStackTrace();
         }
         return ;
      }

      private static void execSQL(Connection con, String sql) throws SQLException {
      Statement stmt = con.createStatement();
      stmt.executeUpdate(sql);
      stmt.close ();
      }

      This sample test program can be compiled using either JDK 1.4.2 or 1.5.0, but needs to be run using JDK 1.5.0.

      Under Java 1.5, this gives the following output:

      2004-08-12.01:55:57.384 TERAJDBC4 DEBUG [Finalizer] com.ncr.teradata.jdbc_4.TDSession@8813f2 new of packet: com.ncr.teradata.jdbc_4.io.TDPacket@c5c3ac
      2004-08-12.01:55:57.384 TERAJDBC4 DEBUG [Finalizer] com.ncr.teradata.jdbc_4.TDSession@1ef8cf3 message dump: byte array length 56 (0x38), offset 0 (0x0), dump length 56 (0x38)
      00000 03 01 08 00 00 00 00 00 00 04 00 00 00 00 00 00 |................|
      00010 00 00 00 00 00 00 07 c5 00 00 00 00 00 00 00 04 |.......?........|
      00020 00 00 00 02 00 bf 00 00 00 00 00 00 00 00 00 00 |.....?..........|
      00030 00 00 00 00 00 25 00 04 |.....%..|

      2004-08-12.01:55:57.384 TERAJDBC4 DEBUG [Finalizer] com.ncr.teradata.jdbc_4.TDSession@8813f2 Raw packet transmit: byte array length 65156 (0xfe84), offset 0 (0x0), dump length 56 (0x38)
      00000 03 01 08 00 00 00 00 00 00 04 00 00 00 00 00 00 |................|
      00010 00 00 00 00 00 00 07 c5 00 00 00 00 00 00 00 04 |.......?........|
      00020 00 00 00 02 00 bf 00 00 00 00 00 00 00 00 00 00 |.....?..........|
      00030 00 00 00 00 00 25 00 04 |.....%..|

      2004-08-12.01:55:57.384 TERAJDBC4 DEBUG [Finalizer] com.ncr.teradata.jdbc_4.TDSession@1ef8cf3 writing 56 bytes

      Actually the finalizer also generate an exception due to the closed socket, but this issue is another issue and will be reported separately.

      The issue here is that because the generated connection object is not referenced, so the Java garbage collector starts and the finalizer gets running.

      ACTUAL -
      2004-08-12.01:55:57.384 TERAJDBC4 DEBUG [Finalizer] com.ncr.teradata.jdbc_4.TDSession@8813f2 new of packet: com.ncr.teradata.jdbc_4.io.TDPacket@c5c3ac
      2004-08-12.01:55:57.384 TERAJDBC4 DEBUG [Finalizer] com.ncr.teradata.jdbc_4.TDSession@1ef8cf3 message dump: byte array length 56 (0x38), offset 0 (0x0), dump length 56 (0x38)
      00000 03 01 08 00 00 00 00 00 00 04 00 00 00 00 00 00 |................|
      00010 00 00 00 00 00 00 07 c5 00 00 00 00 00 00 00 04 |.......?........|
      00020 00 00 00 02 00 bf 00 00 00 00 00 00 00 00 00 00 |.....?..........|
      00030 00 00 00 00 00 25 00 04 |.....%..|

      2004-08-12.01:55:57.384 TERAJDBC4 DEBUG [Finalizer] com.ncr.teradata.jdbc_4.TDSession@8813f2 Raw packet transmit: byte array length 65156 (0xfe84), offset 0 (0x0), dump length 56 (0x38)
      00000 03 01 08 00 00 00 00 00 00 04 00 00 00 00 00 00 |................|
      00010 00 00 00 00 00 00 07 c5 00 00 00 00 00 00 00 04 |.......?........|
      00020 00 00 00 02 00 bf 00 00 00 00 00 00 00 00 00 00 |.....?..........|
      00030 00 00 00 00 00 25 00 04 |.....%..|

      2004-08-12.01:55:57.384 TERAJDBC4 DEBUG [Finalizer] com.ncr.teradata.jdbc_4.TDSession@1ef8cf3 writing 56 bytes

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.sql.*;
      import javax.sql.*;
      import java.lang.reflect.*;
      import java.util.*;

      /**
       * This sample program tests the com.sun.rowset.JdbcRowSetImpl
       * (java.lang.String url, java.lang.String user, java.lang.String password)
       * class with the Teradata JDBC Driver. This program can be compiled
       * with JDK 1.4, but it requires JDK 1.5 to run.
       */
      public class RowSetImplTest {

      public static void main (String args[]) {
         String url="jdbc:teradata://DatabaseName/TMODE=ANSI,LOG=DEBUG";
         String user = "username";
         String password = "password";
         String tableName = "RowSetImplTest";
         String sqlCreate = "CREATE TABLE " + tableName + "(c1 NOT NULL PRIMARY KEY integer)";
         String sqlSelect = "SELECT * FROM " + tableName + " order by c1";
         String sqlDrop = "DROP TABLE " + tableName ;
         int max = 3;

         try {
            // Initialize Connection and JdbcRowSet
            Class.forName ("com.ncr.teradata.TeraDriver");
            Connection con = DriverManager.getConnection (url, user, password) ;
            try {
               try {
      execSQL(con, sqlDrop);
               }
               catch (SQLException ex) {
      System.out.println ("Ignoring drop-table exception: " + ex);
               }
               try {
      execSQL(con, sqlCreate);
               }
               catch (SQLException ex) {
      System.out.println ("Exception during table creation: " + ex);
               }
               try {
      System.out.println ("Creating JdbcRowSet...");
      // Initialize test data
      Random rand = new Random(0);
      int[] value = new int[max];
      for (int i = 0; i < max; i++) {
      value[i] = rand.nextInt(); System.out.println ("" + value[i]);
      }
      Arrays.sort(value);
      // Insert test data into table
      PreparedStatement ps = con.prepareStatement("INSERT INTO " + tableName + " (?);");
      for (int i = 0; i < max; i++) {
      ps.setInt(1, value[i]);
      ps.executeUpdate();
      }
      ps.close();

                      Class cls = Class.forName("com.sun.rowset.JdbcRowSetImpl");
      Constructor cn = cls.getConstructor(new Class[] { String.class, String.class, String.class });
      RowSet jrs = (RowSet)cn.newInstance(new Object[] { url, user, password }); jrs.setCommand(sqlSelect);
      jrs.execute();
      System.out.println ("Output the test data: ");
      for (int i = 0; i < max; i++) {
      jrs.next();
      int value2 = jrs.getInt(1);
      System.out.println ("" + value2);
      if (value[i] != value2) {
      System.out.println ("Error: returned value != inserted value !");
      }
      }

      if (jrs != null)
      jrs.close();
               }
               finally {
      execSQL(con, sqlDrop);
               }
            }
            finally {
      con.close ();
            }
         }
         catch (Exception ex) {
      ex.printStackTrace();
         }
         return ;
      }

      private static void execSQL(Connection con, String sql) throws SQLException {
      Statement stmt = con.createStatement();
      stmt.executeUpdate(sql);
      stmt.close ();
      }
      }
      ---------- END SOURCE ----------
      (Incident Review ID: 296810)
      ======================================================================

            ssharmasunw Sushmita Sharma (Inactive)
            rmandalasunw Ranjith Mandala (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: