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/03 20:47:13 UTC

svn commit: r701487 - in /db/derby/code/trunk/java: engine/org/apache/derby/impl/jdbc/ testing/org/apache/derby/impl/jdbc/

Author: kmarsden
Date: Fri Oct  3 11:47:12 2008
New Revision: 701487

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


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

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedBlob.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedBlob.java?rev=701487&r1=701486&r2=701487&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedBlob.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedBlob.java Fri Oct  3 11:47:12 2008
@@ -133,7 +133,7 @@
      EmbedBlob(byte [] blobBytes,EmbedConnection con) throws SQLException {
         super(con);
          try {
-             control = new LOBStreamControl (con.getDBName(), blobBytes);
+             control = new LOBStreamControl (con, blobBytes);
              materialized = true;
              streamPositionOffset = Integer.MIN_VALUE;
              //add entry in connection so it can be cleared 
@@ -173,7 +173,7 @@
                 SanityManager.ASSERT(dvdBytes != null,"blob has a null value underneath");
             try {
                 control = new LOBStreamControl (
-                            getEmbedConnection().getDBName(), dvdBytes);
+                            getEmbedConnection(), dvdBytes);
             } catch (IOException e) {
                 throw StandardException.newException (
                                         SQLState.SET_STREAM_FAILURE, e);
@@ -843,7 +843,7 @@
                 control.write (bytes, offset, len, pos - 1);
             }
             else {
-                control = new LOBStreamControl (getEmbedConnection().getDBName());
+                control = new LOBStreamControl (getEmbedConnection());
                 control.copyData (myStream, length());
                 control.write(bytes, offset, len, pos - 1);
                 myStream.close();
@@ -885,7 +885,7 @@
                 }
                 else {
                     control = new LOBStreamControl (
-                                            getEmbedConnection().getDBName());
+                                            getEmbedConnection());
                     control.copyData (myStream, pos - 1);
                     myStream.close ();
                     streamLength = -1;
@@ -923,7 +923,7 @@
                     control.truncate (len);
                 }
                 else {
-                    control = new LOBStreamControl (getEmbedConnection().getDBName());
+                    control = new LOBStreamControl (getEmbedConnection());
                     control.copyData (myStream, len);
                     myStream.close();
                     streamLength = -1;

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedClob.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedClob.java?rev=701487&r1=701486&r2=701487&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedClob.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedClob.java Fri Oct  3 11:47:12 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/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java?rev=701487&r1=701486&r2=701487&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/EmbedConnection.java Fri Oct  3 11:47:12 2008
@@ -75,6 +75,7 @@
 import java.sql.SQLWarning;
 import java.sql.Statement;
 
+import java.util.HashSet;
 import java.util.Map;
 import java.util.WeakHashMap;
 import java.util.HashMap;
@@ -150,6 +151,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)
@@ -3077,6 +3086,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();
+					}
+				}
+			}
+		}
 	}
 
 	/**
@@ -3145,4 +3170,30 @@
     public String getCurrentSchemaName() {
         return getLanguageConnection().getCurrentSchemaName();
     }
+    
+    
+	/**
+	 * 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/trunk/java/engine/org/apache/derby/impl/jdbc/LOBStreamControl.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/LOBStreamControl.java?rev=701487&r1=701486&r2=701487&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/LOBStreamControl.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/LOBStreamControl.java Fri Oct  3 11:47:12 2008
@@ -59,16 +59,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;
@@ -76,12 +76,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, StandardException {
-        this.dbName = dbName;
+        this.conn = conn;
         updateCount = 0;
         bufferSize = Math.max (DEFAULT_MAX_BUF_SIZE, data.length);
         write (data, 0, data.length, 0);
@@ -93,7 +93,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
@@ -104,6 +104,7 @@
                     }
                     else
                         tmpFile = new LOBFile (lobFile);
+                    conn.addLobFile(tmpFile);
                     return null;
                 }
             });
@@ -352,6 +353,7 @@
                 read(dataBytes, 0, dataBytes.length, 0);
                 isBytes = true;
                 tmpFile.close();
+                conn.removeLobFile(tmpFile);
                 tmpFile = null;
             } else {
                 tmpFile.setLength(size);
@@ -436,6 +438,7 @@
         if (tmpFile != null) {
             tmpFile.close();
             deleteFile(lobFile);
+            conn.removeLobFile(tmpFile);
             tmpFile = null;
         }
     }
@@ -508,6 +511,7 @@
                 }while (true);
             }            
             oldFile.close();
+            conn.removeLobFile(oldFile);
             deleteFile(oldStoreFile);
         }
         updateCount++;

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/TemporaryClob.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/TemporaryClob.java?rev=701487&r1=701486&r2=701487&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/TemporaryClob.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/jdbc/TemporaryClob.java Fri Oct  3 11:47:12 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/trunk/java/testing/org/apache/derby/impl/jdbc/BiggerTemporaryClobTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derby/impl/jdbc/BiggerTemporaryClobTest.java?rev=701487&r1=701486&r2=701487&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derby/impl/jdbc/BiggerTemporaryClobTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derby/impl/jdbc/BiggerTemporaryClobTest.java Fri Oct  3 11:47:12 2008
@@ -53,7 +53,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/trunk/java/testing/org/apache/derby/impl/jdbc/SmallTemporaryClobTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derby/impl/jdbc/SmallTemporaryClobTest.java?rev=701487&r1=701486&r2=701487&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derby/impl/jdbc/SmallTemporaryClobTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derby/impl/jdbc/SmallTemporaryClobTest.java Fri Oct  3 11:47:12 2008
@@ -55,7 +55,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),