Issue Details (XML | Word | Printable)

Key: DERBY-3799
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Major Major
Assignee: Kristian Waagan
Reporter: Ralf Lovec
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
Derby

NullPointerException when accessing a clob through a pooled connection

Created: 25/Jul/08 01:55 PM   Updated: 04/May/09 06:22 PM
Return to search
Component/s: Network Client
Affects Version/s: 10.4.1.3, 10.5.1.1
Fix Version/s: 10.4.2.0, 10.5.1.1

Time Tracking:
Not Specified

File Attachments:
  Size
File Licensed for inclusion in ASF works derby-3799-1a-checkIfClosed.diff 2008-07-28 02:38 PM Kristian Waagan 10 kB
Environment:
------------------ Java-Informationen ------------------
Java-Version: 1.6.0
Java-Anbieter: Sun Microsystems Inc.
Java-Home: C:\Program Files\Java\jdk1.6.0\jre
Java-Klassenpfad: C:\PHS\db-derby\db-derby-10.4.1.3-bin\lib\derbyclient.jar;C:\PHS\db-derby\db-derby-10.4.1.3-bin\lib\derbytools.jar;C:\PHS\Dvlp\Schop\derby-err\build\classes
Name des Betriebssystems: Windows XP
Architektur des Betriebssystems: x86
Betriebssystemversion: 5.1
Java-Benutzername: Ralf Lovec
Java-Benutzerausgangsverzeichnis: C:\Documents and Settings\Ralf Lovec
Java-Benutzerverzeichnis: C:\PHS\Dvlp\Schop\derby-err
java.specification.name: Java Platform API Specification
java.specification.version: 1.6
--------- Derby-Informationen --------
JRE - JDBC: Java SE 6 - JDBC 4.0
[C:\PHS\db-derby\db-derby-10.4.1.3-bin\lib\derbytools.jar] 10.4.1.3 - (648739)
[C:\PHS\db-derby\db-derby-10.4.1.3-bin\lib\derbyclient.jar] 10.4.1.3 - (648739)
------------------------------------------------------
----------------- Informationen zur L�ndereinstellung -----------------
Aktuelle L�ndereinstellung: [Deutsch/Deutschland [de_DE]]
Es wurde Unterst�tzung f�r die folgende L�ndereinstellung gefunden: [cs]
         Version: 10.4.1.3 - (648739)
Es wurde Unterst�tzung f�r die folgende L�ndereinstellung gefunden: [de_DE]
         Version: 10.4.1.3 - (648739)
Es wurde Unterst�tzung f�r die folgende L�ndereinstellung gefunden: [es]
         Version: 10.4.1.3 - (648739)
Es wurde Unterst�tzung f�r die folgende L�ndereinstellung gefunden: [fr]
         Version: 10.4.1.3 - (648739)
Es wurde Unterst�tzung f�r die folgende L�ndereinstellung gefunden: [hu]
         Version: 10.4.1.3 - (648739)
Es wurde Unterst�tzung f�r die folgende L�ndereinstellung gefunden: [it]
         Version: 10.4.1.3 - (648739)
Es wurde Unterst�tzung f�r die folgende L�ndereinstellung gefunden: [ja_JP]
         Version: 10.4.1.3 - (648739)
Es wurde Unterst�tzung f�r die folgende L�ndereinstellung gefunden: [ko_KR]
         Version: 10.4.1.3 - (648739)
Es wurde Unterst�tzung f�r die folgende L�ndereinstellung gefunden: [pl]
         Version: 10.4.1.3 - (648739)
Es wurde Unterst�tzung f�r die folgende L�ndereinstellung gefunden: [pt_BR]
         Version: 10.4.1.3 - (648739)
Es wurde Unterst�tzung f�r die folgende L�ndereinstellung gefunden: [ru]
         Version: 10.4.1.3 - (648739)
Es wurde Unterst�tzung f�r die folgende L�ndereinstellung gefunden: [zh_CN]
         Version: 10.4.1.3 - (648739)
Es wurde Unterst�tzung f�r die folgende L�ndereinstellung gefunden: [zh_TW]
         Version: 10.4.1.3 - (648739)
------------------------------------------------------

Resolution Date: 01/Aug/08 02:00 PM


 Description  « Hide
After returning a pooled connection to the pool and getting it again a NullPointerException is thrown when a clob field is accessed again. This may be related to the following post: http://mail-archives.apache.org/mod_mbox/db-derby-user/200803.mbox/%3C47CD3431.5020205@sun.com%3E

Here is the stack trace:
java.lang.NullPointerException
        at org.apache.derby.client.am.PreparedStatement.setIntX(Unknown Source)
        at org.apache.derby.client.am.CallableLocatorProcedures.clobGetLength(Unknown Source)
        at org.apache.derby.client.am.Clob.getLocatorLength(Unknown Source)
        at org.apache.derby.client.am.Lob.sqlLength(Unknown Source)
        at org.apache.derby.client.am.Clob.length(Unknown Source)
        at org.apache.derby.client.am.Cursor.getString(Unknown Source)
        at org.apache.derby.client.am.ResultSet.getString(Unknown Source)
        at derbyerr.Main.main(Main.java:65)


Here is the code to reproduce the problem:

package derbyerr;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.sql.PooledConnection;
import org.apache.derby.jdbc.ClientConnectionPoolDataSource;


public class Main {
  
  public static void main (String[] args) {
    org.apache.derby.tools.sysinfo.main (args) ;
    
    ClientConnectionPoolDataSource creator = new ClientConnectionPoolDataSource () ;
    // There should be an empty db named testdb
    creator.setDatabaseName ("testdb") ;
    
    try {
      PooledConnection pc = creator.getPooledConnection () ;
      
      Connection c = pc.getConnection () ;
      PreparedStatement ps ;
      ResultSet rs ;
      String s ;

      // Drop the table "test", if it exsists
      try {
        ps = c.prepareStatement ("drop table test") ;
        ps.execute () ;
        ps.close () ;
      } catch (Exception e) {
      }
      
      // Create a test table with a clob field
      ps = c.prepareStatement ("create table test (pkey varchar(255) not null primary key, value clob)") ;
      ps.execute () ;
      ps.close () ;
      
      // Insert a record
      ps = c.prepareStatement ("insert into test values ('123', 'abc')") ;
      ps.execute () ;
      ps.close () ;

      // Query the record and...
      ps = c.prepareStatement ("select * from test") ;
      rs = ps.executeQuery () ;
      rs.next () ;
      // ...access the clob field - this works
      s = rs.getString (2) ;
      assert s.equals ("abc") ;
      rs.close () ;
      ps.close () ;
      
      // Simulate connection pooling: close the connection and get it again
      c.close () ;
      c = pc.getConnection () ;

      // Now again query the record...
      ps = c.prepareStatement ("select * from test") ;
      rs = ps.executeQuery () ;
      rs.next () ;
      // ...and access the clob - this fails
      s = rs.getString (2) ;
      assert s.equals ("abc") ;
      rs.close () ;
      ps.close () ;
      
    } catch (Exception e) {
      e.printStackTrace () ;
    }
  }
  
}


 All   Comments   Work Log   Change History   Subversion Commits      Sort Order: Ascending order - Click to sort in descending order
Kristian Waagan added a comment - 25/Jul/08 03:01 PM
I had a quick look at the bug. Thank you very much for the repro. I verified that the bug is also present in trunk (development version).

At the moment I don't have much to offer, but you can run with JDBC statement caching as a workaround by adding "creator.setMaxStatements(<how-many-statements-you-want-to-cache>);".
Please note that the client-side JDBC statement cache is not ready for production with 10.4.1.3. There were some bugs on the server in how the connections were handled, causing a resource leak that lead to increased GC overhead.

The cause of the NPE is that the parameter meta data has been nulled out and not been reset. I hope to be able to have a closer look on Monday.

Kristian Waagan added a comment - 28/Jul/08 02:38 PM
'derby-3799-1a-checkIfClosed.diff' fixes the reported problem and adds a regression test.

When a logical connection is closed all open statements are closed. The LOB stored procedure code did not detect this, as it only checked if the reference to the CallableStatement was null or not.
I fixed this by also checking if the CallableStatement is open on the client. The fix implies that the stored procedure calls must be prepared for each logical connection, if the LOB stored procedures are needed. This does not happen when the JDBC statement cache is enabled.

Comments on the fix approach and the patch are welcome!

Kristian Waagan added a comment - 01/Aug/08 02:00 PM
Committed patch 1a to trunk with revision 681694.
Backported to 10.4 with revision 681697.

Issue can be closed when the fix has been verified.

Ralf Lovec added a comment - 03/Aug/08 08:41 PM
I have tested trunk and the backport to 10.4 and in both versions the problem has been resolved.

Kristian Waagan added a comment - 04/Aug/08 06:34 AM
Thanks for the quick feedback, Ralf :)