You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by km...@apache.org on 2008/10/07 19:36:51 UTC

svn commit: r702554 - in /db/derby/code/branches/10.3/java: engine/org/apache/derby/impl/jdbc/ testing/org/apache/derby/impl/jdbc/

Author: kmarsden
Date: Tue Oct  7 10:36:51 2008
New Revision: 702554

URL: http://svn.apache.org/viewvc?rev=702554&view=rev
Log:
DERBY-3655 errror in nightly regression test: LobStreamsTest:encryptedjunit.framework.AssertionFailedError removing temporary lob file.

DERBY-3883  LOBStreamControl.replaceBytes() leaves temporary files open



Modified:
    db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/EmbedBlob.java
    db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/EmbedClob.java
    db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java
    db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/LOBStreamControl.java
    db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/TemporaryClob.java
    db/derby/code/branches/10.3/java/testing/org/apache/derby/impl/jdbc/BiggerTemporaryClobTest.java
    db/derby/code/branches/10.3/java/testing/org/apache/derby/impl/jdbc/SmallTemporaryClobTest.java

Modified: db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/EmbedBlob.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/EmbedBlob.java?rev=702554&r1=702553&r2=702554&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/EmbedBlob.java (original)
+++ db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/EmbedBlob.java Tue Oct  7 10:36:51 2008
@@ -113,7 +113,7 @@
      EmbedBlob(byte [] blobBytes,EmbedConnection con) throws SQLException {
         super(con);
          try {
-             control = new LOBStreamControl (con.getDBName(), blobBytes);
+             control = new LOBStreamControl (con, blobBytes);
              materialized = true;
              //add entry in connection so it can be cleared 
              //when transaction is not valid
@@ -151,7 +151,7 @@
                 SanityManager.ASSERT(dvdBytes != null,"blob has a null value underneath");
             try {
                 control = new LOBStreamControl (
-                            getEmbedConnection().getDBName(), dvdBytes);
+                            getEmbedConnection(), dvdBytes);
             }
             catch (SQLException e) {
                 throw StandardException.newException (e.getSQLState());
@@ -791,7 +791,7 @@
                 len = (int) control.write (bytes, offset, len, pos - 1);
             }
             else {
-                control = new LOBStreamControl (getEmbedConnection().getDBName());
+                control = new LOBStreamControl (getEmbedConnection());
                 control.copyData (myStream, length());
                 len = (int) control.write(bytes, offset, len, pos - 1);
                 myStream.close();
@@ -832,7 +832,7 @@
                 }
                 else {
                     control = new LOBStreamControl (
-                                            getEmbedConnection().getDBName());
+                                            getEmbedConnection());
                     control.copyData (myStream, pos - 1);
                     myStream.close ();
                     materialized = true;
@@ -869,7 +869,7 @@
                     control.truncate (len);
                 }
                 else {
-                    control = new LOBStreamControl (getEmbedConnection().getDBName());
+                    control = new LOBStreamControl (getEmbedConnection());
                     control.copyData (myStream, len);
                     myStream.close();
                     materialized = true;

Modified: db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/EmbedClob.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/EmbedClob.java?rev=702554&r1=702553&r2=702554&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/EmbedClob.java (original)
+++ db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/EmbedClob.java Tue Oct  7 10:36:51 2008
@@ -90,7 +90,7 @@
      */
     EmbedClob(EmbedConnection con) throws SQLException {
         super(con);
-        this.clob = new TemporaryClob (con.getDBName(), this);
+        this.clob = new TemporaryClob (this);
         con.addLOBReference (this);
     }
 
@@ -119,8 +119,8 @@
         // See if a String or a stream will be the source of the Clob.
         if (storeStream == null) {
             try {
-                clob = new TemporaryClob(con.getDBName(),
-                        dvd.getString(), this);
+                clob = new TemporaryClob(dvd.getString(),
+                        this);
             }
             catch (SQLException sqle) {
                 throw StandardException.newException (sqle.getSQLState(), sqle);

Modified: db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java?rev=702554&r1=702553&r2=702554&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java (original)
+++ db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java Tue Oct  7 10:36:51 2008
@@ -61,11 +61,13 @@
 import java.sql.SQLWarning;
 import java.sql.Statement;
 
+import java.util.HashSet;
 import java.util.Map;
 import java.util.WeakHashMap;
 import java.util.HashMap;
 import java.util.Properties;
 import java.util.Iterator;
+import java.io.IOException;
 
 import org.apache.derby.iapi.jdbc.EngineLOB;
 import org.apache.derby.impl.jdbc.authentication.NoneAuthenticationServiceImpl;
@@ -136,6 +138,14 @@
      */
     private WeakHashMap lobReferences = null;
 
+    // Set to keep track of the open LOBFiles, so they can be closed at the end of 
+    // the transaction. This would normally happen as lobReferences are freed as they
+    // get garbage collected after being removed from the WeakHashMap, but it is 
+    // possible that finalization will not have occurred before the user tries to 
+    // remove the database (DERBY-3655).  Therefore we keep this set so that we can
+    // explicitly close the files.
+    private HashSet lobFiles;
+    
 	//////////////////////////////////////////////////////////
 	// STATE (copied to new nested connections, but nesting
 	// specific)
@@ -2379,6 +2389,22 @@
         if (rootConnection.lobHashMap != null) {
             rootConnection.lobHashMap.clear ();
         }
+		
+		synchronized (this) {   
+			if (lobFiles != null) {       
+				Iterator it = lobFiles.iterator();
+				while (it.hasNext()) {
+					try {
+						((LOBFile) it.next()).close();
+					} catch (IOException ioe) {
+						throw Util.javaException(ioe);
+					}
+					finally {
+						lobFiles.clear();
+					}
+				}
+			}
+		}
 	}
 
 	/**
@@ -2436,4 +2462,30 @@
     public void cancelRunningStatement() {
         getLanguageConnection().getStatementContext().cancel();
     }
+    
+    
+	/**
+	 * Add a temporary lob file to the lobFiles set.
+	 * This will get closed at transaction end or removed as the lob is freed.
+	 * @param lobFile  LOBFile to add
+	 */
+	void addLobFile(LOBFile lobFile) {
+		synchronized (this) {
+			if (lobFiles == null)
+				lobFiles = new HashSet();
+			lobFiles.add(lobFile);
+		}
+	}
+    
+	/**
+	 * Remove LOBFile from the lobFiles set. This will occur when the lob 
+	 * is freed or at transaction end if the lobFile was removed from the 
+	 * WeakHashMap but not finalized.
+	 * @param lobFile  LOBFile to remove.
+	 */
+	void removeLobFile(LOBFile lobFile) {
+		synchronized (this) {
+			lobFiles.remove(lobFile);
+		}
+	}
 }

Modified: db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/LOBStreamControl.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/LOBStreamControl.java?rev=702554&r1=702553&r2=702554&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/LOBStreamControl.java (original)
+++ db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/LOBStreamControl.java Tue Oct  7 10:36:51 2008
@@ -65,16 +65,16 @@
     private byte [] dataBytes = new byte [0];
     private boolean isBytes = true;
     private final int bufferSize;
-    private String dbName;
+    private final EmbedConnection conn;
     private long updateCount;
     private static final int DEFAULT_MAX_BUF_SIZE = 4096;
 
     /**
      * Creates an empty LOBStreamControl.
-     * @param dbName database name
+     * @param conn Connection for this lob
      */
-    LOBStreamControl (String dbName) {
-        this.dbName = dbName;
+    LOBStreamControl (EmbedConnection conn) {
+        this.conn = conn;
         updateCount = 0;
         //default buffer size
         bufferSize = DEFAULT_MAX_BUF_SIZE;
@@ -82,12 +82,12 @@
 
     /**
      * Creates a LOBStreamControl and initializes with a bytes array.
-     * @param dbName database name
+     * @param conn Connection for this lob
      * @param data initial value
      */
-    LOBStreamControl (String dbName, byte [] data)
+    LOBStreamControl (EmbedConnection conn, byte [] data)
                 throws IOException, SQLException, StandardException {
-        this.dbName = dbName;
+        this.conn = conn;
         updateCount = 0;
         bufferSize = Math.max (DEFAULT_MAX_BUF_SIZE, data.length);
         write (data, 0, data.length, 0);
@@ -99,7 +99,7 @@
             AccessController.doPrivileged (new PrivilegedExceptionAction() {
                 public Object run() throws IOException, StandardException {
                     Object monitor = Monitor.findService(
-                            Property.DATABASE_MODULE, dbName);
+                            Property.DATABASE_MODULE, conn.getDBName());
                     DataFactory df =  (DataFactory) Monitor.findServiceModule(
                             monitor, DataFactory.MODULE);
                     //create a temporary file
@@ -110,6 +110,7 @@
                     }
                     else
                         tmpFile = new LOBFile (lobFile);
+                    conn.addLobFile(tmpFile);
                     return null;
                 }
             });
@@ -360,6 +361,7 @@
                 read(dataBytes, 0, dataBytes.length, 0);
                 isBytes = true;
                 tmpFile.close();
+                conn.removeLobFile(tmpFile);
                 tmpFile = null;
             } else {
                 try {
@@ -426,6 +428,7 @@
         if (tmpFile != null) {
             tmpFile.close();
             deleteFile(lobFile);
+            conn.removeLobFile(tmpFile);
             tmpFile = null;
         }
     }
@@ -497,9 +500,10 @@
                         break;
                     tmpFile.write (tmpByte, 0, rdLen);
                 }while (true);
-                oldFile.close();
-                deleteFile(oldStoreFile);
             }            
+            oldFile.close();
+            conn.removeLobFile(oldFile);
+            deleteFile(oldStoreFile);
         }
         updateCount++;
         return stPos + buf.length;

Modified: db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/TemporaryClob.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/TemporaryClob.java?rev=702554&r1=702553&r2=702554&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/TemporaryClob.java (original)
+++ db/derby/code/branches/10.3/java/engine/org/apache/derby/impl/jdbc/TemporaryClob.java Tue Oct  7 10:36:51 2008
@@ -73,7 +73,7 @@
                                          ConnectionChild conChild,
                                          InternalClob clob)
             throws IOException, SQLException {
-        TemporaryClob newClob = new TemporaryClob(dbName, conChild);
+        TemporaryClob newClob = new TemporaryClob(conChild);
         newClob.copyClobContent(clob);
         return newClob;
     }
@@ -94,7 +94,7 @@
                                          InternalClob clob,
                                          long length)
             throws IOException, SQLException {
-        TemporaryClob newClob = new TemporaryClob(dbName, conChild);
+        TemporaryClob newClob = new TemporaryClob(conChild);
         newClob.copyClobContent(clob, length);
         return newClob;
     }
@@ -102,18 +102,17 @@
     /**
      * Constructs a <code>TemporaryClob</code> object used to perform
      * operations on a CLOB value.
-     * 
-     * @param dbName name of the database the CLOB value belongs to
      * @param conChild connection object used to obtain synchronization object
+     * 
      * @throws NullPointerException if <code>conChild</code> is
      *      <code>null</code>
      */
-    TemporaryClob (String dbName, ConnectionChild conChild) {
+    TemporaryClob (ConnectionChild conChild) {
         if (conChild == null) {
             throw new NullPointerException("conChild cannot be <null>");
         }
         this.conChild = conChild;
-        this.bytes = new LOBStreamControl(dbName);
+        this.bytes = new LOBStreamControl(conChild.getEmbedConnection());
     }
 
     /**
@@ -148,18 +147,16 @@
     /**
      * Constructs a <code>TemporaryClob</code> object and
      * initializes with a initial String.
-     * 
-     * @param dbName name of the database the CLOB value belongs to
      * @param data initial value in String
      * @param conChild connection object used to obtain synchronization object
      */
-    TemporaryClob (String dbName, String data, ConnectionChild conChild)
+    TemporaryClob (String data, ConnectionChild conChild)
                           throws IOException, SQLException, StandardException {
         if (conChild == null) {
             throw new NullPointerException("conChild cannot be <null>");
         }
         this.conChild = conChild;
-        bytes = new LOBStreamControl(dbName, getByteFromString (data));
+        bytes = new LOBStreamControl(conChild.getEmbedConnection(), getByteFromString (data));
     }
     /**
      * Finds the corresponding byte position for the given UTF-8 character

Modified: db/derby/code/branches/10.3/java/testing/org/apache/derby/impl/jdbc/BiggerTemporaryClobTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/testing/org/apache/derby/impl/jdbc/BiggerTemporaryClobTest.java?rev=702554&r1=702553&r2=702554&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/testing/org/apache/derby/impl/jdbc/BiggerTemporaryClobTest.java (original)
+++ db/derby/code/branches/10.3/java/testing/org/apache/derby/impl/jdbc/BiggerTemporaryClobTest.java Tue Oct  7 10:36:51 2008
@@ -52,7 +52,7 @@
         super.bytesPerChar = BYTES_PER_CHAR;
         EmbedStatement embStmt = (EmbedStatement)createStatement();
         EmbedConnection embCon =(EmbedConnection)getConnection();
-        iClob = new TemporaryClob(embCon.getDBName(), embStmt);
+        iClob = new TemporaryClob(embStmt);
         transferData(
             new LoopingAlphabetReader(CLOBLENGTH, CharAlphabet.cjkSubset()),
             iClob.getWriter(1L),

Modified: db/derby/code/branches/10.3/java/testing/org/apache/derby/impl/jdbc/SmallTemporaryClobTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.3/java/testing/org/apache/derby/impl/jdbc/SmallTemporaryClobTest.java?rev=702554&r1=702553&r2=702554&view=diff
==============================================================================
--- db/derby/code/branches/10.3/java/testing/org/apache/derby/impl/jdbc/SmallTemporaryClobTest.java (original)
+++ db/derby/code/branches/10.3/java/testing/org/apache/derby/impl/jdbc/SmallTemporaryClobTest.java Tue Oct  7 10:36:51 2008
@@ -54,7 +54,7 @@
         super.bytesPerChar = BYTES_PER_CHAR;
         EmbedStatement embStmt = (EmbedStatement)createStatement();
         EmbedConnection embCon =(EmbedConnection)getConnection();
-        iClob = new TemporaryClob(embCon.getDBName(), embStmt);
+        iClob = new TemporaryClob(embStmt);
         transferData(
             new LoopingAlphabetReader(CLOBLENGTH, CharAlphabet.tamil()),
             iClob.getWriter(1L),