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

Socket closed when running Java garbage collector & finalizer with JDK 1.5.0

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Not an Issue
    • Icon: P4 P4
    • None
    • 5.0
    • core-libs
    • x86
    • windows_xp



      Name: js151677 Date: 08/13/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 :
      When an object instance is generated and unreferenced, for example,

      java.sql.DriverManager.getConnection (url, user, password);

      (
      The correct way is:
      java.sql.Connection con = java.sql.DriverManager.getConnection (url, user, password);
      )

      The Java garbage collector will starts running and the finalizer will get running to collect the referenced object.

      Under JDk 1.4.x, this garbage collection process will be successfully completed, the socket is not closed when finalizer writes to the SocketOutputStream.

      However, under JDK 1.5.0-beta2, the finalizer thread will generate a "java.net.SocketException: Socket closed" exception
      since the socket gets closed when the finalizer tries to write to the SocketOutputStream during the connection closing process.

      Therefore, the issue is: when running under JDK 1.5.0-beta2, the socket is closed when the finalizer closes the unreferenced connection, but JDK 1.4.x doesn't have this issue.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Write code that uses a JDBC driver to generate a java.sql.Connection nut it is not referenced.
      The program doesn't close the connection after that. The System.gc() is called to run garbage collector and finalizer.
      Under JDK 1.4.x, the garbage collection/finalizer process will be successfully finished, but when running JDK 1.5.0-beta2,
      a "java.net.SocketException: Socket closed" exception will be generated when the finalizer tries to write to the SocketOutputStream
      since the socket has already been closed.

      The 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 to reproduce the socket exception.

      Reproducing Steps:
      (1) Generate the sample test program shown below:

      import java.sql.*;
      /**
       * This sample program tests that when the connection object is generated and unreferenced,
       * Java Garbage collector starts and finalizer gets running. Under JDK 1.4.2, the finalizer will
       * successfully finish it, but under JDk 1.5.0-beta2, a "java.net.SocketException: Socket closed"
       * will be generated.
       * This program can be compiled with JDK 1.4 or JDK 1.5.0, but it requires JDK 1.5.0 to run the test
       * for generating the expected exception.
       */
      public class FinalizerSocketClosedTest {
      public static void main (String args[]) {
         String url="jdbc:teradata://DatabaseName/TMODE=ANSI";
         String user = "username";
         String password = "password";
         String tableName = "FinalizerSocketClosedTest";
         try {
      System.out.println ("Opening connection") ;
      Class.forName ("com.ncr.teradata.TeraDriver");
      DriverManager.getConnection (url, user, password) ;
      System.gc();
      System.out.println("System.gc() done!");
      Thread.sleep(5000);
      System.out.println("Thread.sleep() done!");
         }
         catch (Exception ex) {
      ex.printStackTrace();
         }
         return;
      }
      }

      (2) Use Teradata JDBC driver/Teradata Database or any other database driver/database for testing
        Note: Teradata JDBC driver can be downloaded via www.teradata.com
      (3) Compile the test program under either JDK 1.4.x or JDK 1.5.0-beta2
      (4) Run the program under JDk 1.5.0-beta2

      ACTUAL -
      2004-08-12.02:38:38.042 TERAJDBC4 DEBUG [Finalizer] com.ncr.teradata.jdbc_4.TDSession@8813f2 Getting packet from pool: com.ncr.teradata.jdbc_4.io.TDPacket@5ac072
      2004-08-12.02:38:38.042 TERAJDBC4 DEBUG [Finalizer] com.ncr.teradata.jdbc_4.TDSession@8813f2 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 d3 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.02:38:38.042 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 d3 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.02:38:38.042 TERAJDBC4 DEBUG [Finalizer] com.ncr.teradata.jdbc_4.TDSession@8813f2 writing 56 bytes
      2004-08-12.02:38:38.042 TERAJDBC4 ERROR [Finalizer] com.ncr.teradata.jdbc_4.TDSession@8813f2 Packet stream write error: local=0.0.0.0/0.0.0.0:2444 remote=cyclopsCOP1/141.206.37.123:1025 cid=863399 sess=2003 Thu Aug 12 14:38:38 PDT 2004 java.net.SocketException: Socket closed
      at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:99)
      at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
      at com.ncr.teradata.jdbc_4.io.TDNetworkIO1_3Impl.write(TDNetworkIO1_3Impl.java:365)
      at com.ncr.teradata.jdbc_4.io.TDPacketStream1_3Impl.writeStream(TDPacketStream1_3Impl.java:739)
      at com.ncr.teradata.jdbc_4.statemachine.LogOffState.action(LogOffState.java:67)
      at com.ncr.teradata.jdbc_4.statemachine.LogoffController.run(LogoffController.java:44)
      at com.ncr.teradata.jdbc_4.TDSession.close(TDSession.java:129)
      at com.ncr.teradata.jdbc_3.ifjdbc_4.TeraLocalConnection.close(TeraLocalConnection.java:292)
      at com.ncr.teradata.TeraConnection.finalize(TeraConnection.java:141)
      at java.lang.ref.Finalizer.invokeFinalizeMethod(Native Method)
      at java.lang.ref.Finalizer.runFinalizer(Finalizer.java:83)
      at java.lang.ref.Finalizer.access$100(Finalizer.java:14)
      at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:160)
      2004-08-12.02:38:38.073 TERAJDBC4 ERROR [Finalizer] com.ncr.teradata.jdbc_4.TDSession@8813f2 Exception begin-log-stack-trace>>> com.ncr.teradata.jdbc_4.util.JDBCException: [NCR] [Teradata JDBC Driver] : 08S01 804 : I/O Error, Socket closed.
      Packet stream write error: local=0.0.0.0/0.0.0.0:2444 remote=cyclopsCOP1/141.206.37.123:1025 cid=863399 sess=2003 Thu Aug 12 14:38:38 PDT 2004 java.net.SocketException: Socket closed
      at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:99)
      at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
      at com.ncr.teradata.jdbc_4.io.TDNetworkIO1_3Impl.write(TDNetworkIO1_3Impl.java:365)
      at com.ncr.teradata.jdbc_4.io.TDPacketStream1_3Impl.writeStream(TDPacketStream1_3Impl.java:739)
      at com.ncr.teradata.jdbc_4.statemachine.LogOffState.action(LogOffState.java:67)
      at com.ncr.teradata.jdbc_4.statemachine.LogoffController.run(LogoffController.java:44)
      at com.ncr.teradata.jdbc_4.TDSession.close(TDSession.java:129)
      at com.ncr.teradata.jdbc_3.ifjdbc_4.TeraLocalConnection.close(TeraLocalConnection.java:292)
      at com.ncr.teradata.TeraConnection.finalize(TeraConnection.java:141)
      at java.lang.ref.Finalizer.invokeFinalizeMethod(Native Method)
      at java.lang.ref.Finalizer.runFinalizer(Finalizer.java:83)
      at java.lang.ref.Finalizer.access$100(Finalizer.java:14)
      at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:160)
      at com.ncr.teradata.jdbc_4.util.ErrorFactory.makeDriverJDBCException(ErrorFactory.java:80)
      at com.ncr.teradata.jdbc_4.util.ErrorFactory.makeDriverJDBCException(ErrorFactory.java:47)
      at com.ncr.teradata.jdbc_4.util.ErrorFactory.makeIoJDBCException(ErrorFactory.java:137)
      at com.ncr.teradata.jdbc_4.io.TDPacketStream1_3Impl.analyzeError(TDPacketStream1_3Impl.java:781)
      at com.ncr.teradata.jdbc_4.io.TDPacketStream1_3Impl.writeStream(TDPacketStream1_3Impl.java:741)
      at com.ncr.teradata.jdbc_4.statemachine.LogOffState.action(LogOffState.java:67)
      at com.ncr.teradata.jdbc_4.statemachine.LogoffController.run(LogoffController.java:44)
      at com.ncr.teradata.jdbc_4.TDSession.close(TDSession.java:129)
      at com.ncr.teradata.jdbc_3.ifjdbc_4.TeraLocalConnection.close(TeraLocalConnection.java:292)
      at com.ncr.teradata.TeraConnection.finalize(TeraConnection.java:141)
      at java.lang.ref.Finalizer.invokeFinalizeMethod(Native Method)
      at java.lang.ref.Finalizer.runFinalizer(Finalizer.java:83)
      at java.lang.ref.Finalizer.access$100(Finalizer.java:14)
      at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:160)
       <<<end-log-stack-trace
      System.gc() done!
      Thread.sleep() done!

      The issue here is that because the socket is closed when the finalizer tries to write to the SocketOutputStream, so the exception "java.net.SocketException: Socket closed" is generated.

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      Here is the complete and compilable source code:

      import java.sql.*;
      /**
       * This sample program tests that when the connection object is
       * generated and unreferenced, Java Garbage collector starts and
       * finalizer gets running. Under JDK 1.4.2, the finalizer will successfully
       * finish it, but under JDk 1.5.0-beta2, a "java.net.SocketException: Socket
       * closed" will be generated.
       * This program can be compiled with JDK 1.4 or JDK 1.5.0, but it
       * requires JDK 1.5.0 to run the test for generating the expected exception.
       */
      public class FinalizerSocketClosedTest {
      public static void main (String args[]) {
         String url="jdbc:teradata://DatabaseName/TMODE=ANSI,LOG=DEBUG";
         String user = "username";
         String password = "password";
         String tableName = "FinalizerSocketClosedTest";
         try {
      System.out.println ("Opening connection") ;
      Class.forName ("com.ncr.teradata.TeraDriver");
      DriverManager.getConnection (url, user, password) ;
      System.gc();
      System.out.println("System.gc() done!");
      Thread.sleep(5000);
      System.out.println("Thread.sleep() done!");
         }
         catch (Exception ex) {
      ex.printStackTrace();
         }
         return;
      }
      }
      ---------- END SOURCE ----------
      (Incident Review ID: 296817)
      ======================================================================

            ahandasunw Amit Handa (Inactive)
            jssunw Jitender S (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: