Reactivate tests. Make database caches more robust
diff --git a/commons-jcs-core/pom.xml b/commons-jcs-core/pom.xml
index e7bc878..be95c6d 100644
--- a/commons-jcs-core/pom.xml
+++ b/commons-jcs-core/pom.xml
@@ -130,10 +130,6 @@
                   sensitive.
               -->
               <!-- You need to manually run these test cases. -->
-              <exclude>**/BlockDiskElementDescriptorUnitTest.java</exclude>
-              <exclude>**/HSQLDiskCacheConcurrentUnitTest.java</exclude>
-              <exclude>**/HSQLDiskCacheUnitTest.java</exclude>
-              <exclude>**/IndexedDiskCacheOptimizationUnitTest.java</exclude>
               <exclude>**/TestTCPLateralUnitTest.java</exclude>
               <exclude>**/UDPDiscoveryUnitTest.java</exclude>
               <!-- Causes hang in Continuum -->
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/JDBCDiskCache.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/JDBCDiskCache.java
index 508eec2..a60b81d 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/JDBCDiskCache.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/JDBCDiskCache.java
@@ -21,6 +21,7 @@
 
 import java.io.IOException;
 import java.sql.Connection;
+import java.sql.DatabaseMetaData;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
@@ -615,37 +616,44 @@
 
         try (Connection con = getDataSource().getConnection())
         {
-            getTableState().setState( TableState.DELETE_RUNNING );
+            // The shrinker thread might kick in before the table is created
+            // So check if the table exists first
+            DatabaseMetaData dmd = con.getMetaData();
+            ResultSet result = dmd.getTables(null, null,
+                    getJdbcDiskCacheAttributes().getTableName(), null);
 
-            long now = System.currentTimeMillis() / 1000;
-
-            // This is to slow when we push over a million records
-            // String sql = "delete from " +
-            // getJdbcDiskCacheAttributes().getTableName() + " where REGION = '"
-            // + this.getCacheName() + "' and IS_ETERNAL = 'F' and (" + now
-            // + " - UPDATE_TIME_SECONDS) > MAX_LIFE_SECONDS";
-
-            String sql = "delete from " + getJdbcDiskCacheAttributes().getTableName()
-                + " where IS_ETERNAL = ? and REGION = ? and ? > SYSTEM_EXPIRE_TIME_SECONDS";
-
-            try (PreparedStatement psDelete = con.prepareStatement( sql ))
+            if (result.next())
             {
-                psDelete.setString( 1, "F" );
-                psDelete.setString( 2, this.getCacheName() );
-                psDelete.setLong( 3, now );
+                getTableState().setState( TableState.DELETE_RUNNING );
+                long now = System.currentTimeMillis() / 1000;
 
-                setAlive(true);
+                String sql = "delete from " + getJdbcDiskCacheAttributes().getTableName()
+                    + " where IS_ETERNAL = ? and REGION = ? and ? > SYSTEM_EXPIRE_TIME_SECONDS";
 
-                deleted = psDelete.executeUpdate();
+                try (PreparedStatement psDelete = con.prepareStatement( sql ))
+                {
+                    psDelete.setString( 1, "F" );
+                    psDelete.setString( 2, this.getCacheName() );
+                    psDelete.setLong( 3, now );
+
+                    setAlive(true);
+
+                    deleted = psDelete.executeUpdate();
+                }
+                catch ( SQLException e )
+                {
+                    log.error( "Problem creating statement.", e );
+                    setAlive(false);
+                }
+
+                logApplicationEvent( getAuxiliaryCacheAttributes().getName(), "deleteExpired",
+                                     "Deleted expired elements.  URL: " + getDiskLocation() );
             }
-            catch ( SQLException e )
+            else
             {
-                log.error( "Problem creating statement.", e );
-                setAlive(false);
+                log.warn( "Trying to shrink non-existing table [{0}]",
+                        getJdbcDiskCacheAttributes().getTableName() );
             }
-
-            logApplicationEvent( getAuxiliaryCacheAttributes().getName(), "deleteExpired",
-                                 "Deleted expired elements.  URL: " + getDiskLocation() );
         }
         catch ( SQLException e )
         {
diff --git a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/hsql/HSQLDiskCacheFactory.java b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/hsql/HSQLDiskCacheFactory.java
index 186e46b..1afb779 100644
--- a/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/hsql/HSQLDiskCacheFactory.java
+++ b/commons-jcs-core/src/main/java/org/apache/commons/jcs/auxiliary/disk/jdbc/hsql/HSQLDiskCacheFactory.java
@@ -20,10 +20,12 @@
  */
 
 import java.sql.Connection;
-import java.sql.DriverManager;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
-import java.util.concurrent.CopyOnWriteArraySet;
+
+import javax.sql.DataSource;
 
 import org.apache.commons.jcs.auxiliary.AuxiliaryCacheAttributes;
 import org.apache.commons.jcs.auxiliary.disk.jdbc.JDBCDiskCache;
@@ -46,9 +48,6 @@
     /** The logger */
     private static final Log log = LogManager.getLog( HSQLDiskCacheFactory.class );
 
-    /** The databases. */
-    private CopyOnWriteArraySet<String> databases;
-
     /**
      * This factory method should create an instance of the hsqlcache.
      * <p>
@@ -66,70 +65,30 @@
 			IElementSerializer elementSerializer )
 			throws SQLException
     {
-        setupDatabase( (JDBCDiskCacheAttributes) rawAttr );
-        return super.createCache(rawAttr, compositeCacheManager, cacheEventLogger, elementSerializer);
+        // TODO get this from the attributes.
+        System.setProperty( "hsqldb.cache_scale", "8" );
+
+        JDBCDiskCache<K, V> cache = super.createCache(rawAttr, compositeCacheManager,
+                cacheEventLogger, elementSerializer);
+        setupDatabase( cache.getDataSource(), (JDBCDiskCacheAttributes) rawAttr );
+
+        return cache;
     }
 
     /**
-     * Initialize this factory
-     */
-    @Override
-    public void initialize()
-    {
-        super.initialize();
-        this.databases = new CopyOnWriteArraySet<>();
-    }
-
-    /**
-     * Creates the database if it doesn't exist, registers the driver class, etc.
+     * Creates the table if it doesn't exist
      * <p>
-     * @param attributes
+     * @param ds Data Source
+     * @param attributes Cache region configuration
      * @throws SQLException
      */
-    protected void setupDatabase( JDBCDiskCacheAttributes attributes )
+    protected void setupDatabase( DataSource ds, JDBCDiskCacheAttributes attributes )
         throws SQLException
     {
-        if ( attributes == null )
+        try (Connection cConn = ds.getConnection())
         {
-            throw new SQLException( "The attributes are null." );
-        }
-
-        // url should start with "jdbc:hsqldb:"
-        String database = attributes.getUrl() + attributes.getDatabase();
-
-        if ( databases.contains( database ) )
-        {
-            log.info("We already setup database [{0}]", database);
-            return;
-        }
-
-        synchronized (databases)
-        {
-            // TODO get this from the attributes.
-            System.setProperty( "hsqldb.cache_scale", "8" );
-
-            // "org.hsqldb.jdbcDriver"
-            String driver = attributes.getDriverClassName();
-            // "sa"
-            String user = attributes.getUserName();
-            // ""
-            String password = attributes.getPassword();
-
-            try
-            {
-                Class.forName( driver ).newInstance();
-            }
-            catch (Exception e)
-            {
-                throw new SQLException( "Could not initialize driver " + driver, e );
-            }
-
-            Connection cConn = DriverManager.getConnection( database, user, password );
             setupTable( cConn, attributes.getTableName() );
-
-            log.info( "Finished setting up database [{0}]", database);
-
-            databases.add( database );
+            log.info( "Finished setting up table [{0}]", attributes.getTableName());
         }
     }
 
@@ -141,30 +100,29 @@
      */
     protected void setupTable( Connection cConn, String tableName ) throws SQLException
     {
-        // TODO make the cached nature of the table configurable
-        StringBuilder createSql = new StringBuilder();
-        createSql.append( "CREATE CACHED TABLE ").append( tableName );
-        createSql.append( "( " );
-        createSql.append( "CACHE_KEY             VARCHAR(250)          NOT NULL, " );
-        createSql.append( "REGION                VARCHAR(250)          NOT NULL, " );
-        createSql.append( "ELEMENT               BINARY, " );
-        createSql.append( "CREATE_TIME           TIMESTAMP, " );
-        createSql.append( "UPDATE_TIME_SECONDS   BIGINT, " );
-        createSql.append( "MAX_LIFE_SECONDS      BIGINT, " );
-        createSql.append( "SYSTEM_EXPIRE_TIME_SECONDS      BIGINT, " );
-        createSql.append( "IS_ETERNAL            CHAR(1), " );
-        createSql.append( "PRIMARY KEY (CACHE_KEY, REGION) " );
-        createSql.append( ");" );
+        DatabaseMetaData dmd = cConn.getMetaData();
+        ResultSet result = dmd.getTables(null, null, tableName, null);
 
-        try (Statement sStatement = cConn.createStatement())
+        if (!result.next())
         {
-            sStatement.execute( createSql.toString() );
-        }
-        catch ( SQLException e )
-        {
-            if (!"23000".equals(e.getSQLState()))
+            // TODO make the cached nature of the table configurable
+            StringBuilder createSql = new StringBuilder();
+            createSql.append( "CREATE CACHED TABLE ").append( tableName );
+            createSql.append( "( " );
+            createSql.append( "CACHE_KEY             VARCHAR(250)          NOT NULL, " );
+            createSql.append( "REGION                VARCHAR(250)          NOT NULL, " );
+            createSql.append( "ELEMENT               BINARY, " );
+            createSql.append( "CREATE_TIME           TIMESTAMP, " );
+            createSql.append( "UPDATE_TIME_SECONDS   BIGINT, " );
+            createSql.append( "MAX_LIFE_SECONDS      BIGINT, " );
+            createSql.append( "SYSTEM_EXPIRE_TIME_SECONDS      BIGINT, " );
+            createSql.append( "IS_ETERNAL            CHAR(1), " );
+            createSql.append( "PRIMARY KEY (CACHE_KEY, REGION) " );
+            createSql.append( ");" );
+
+            try (Statement sStatement = cConn.createStatement())
             {
-                throw e;
+                sStatement.execute( createSql.toString() );
             }
         }
     }
diff --git a/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/jdbc/hsql/HSQLDiskCacheConcurrentUnitTest.java b/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/jdbc/hsql/HSQLDiskCacheConcurrentUnitTest.java
index 91a0811..4a666b8 100644
--- a/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/jdbc/hsql/HSQLDiskCacheConcurrentUnitTest.java
+++ b/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/jdbc/hsql/HSQLDiskCacheConcurrentUnitTest.java
@@ -1,5 +1,13 @@
 package org.apache.commons.jcs.auxiliary.disk.jdbc.hsql;
 
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.jcs.JCS;
+import org.apache.commons.jcs.access.CacheAccess;
+import org.apache.commons.jcs.engine.behavior.ICacheElement;
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -22,13 +30,6 @@
 import junit.extensions.ActiveTestSuite;
 import junit.framework.Test;
 import junit.framework.TestCase;
-import org.apache.commons.jcs.JCS;
-import org.apache.commons.jcs.access.CacheAccess;
-import org.apache.commons.jcs.engine.behavior.ICacheElement;
-
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
 
 /**
  * Test which exercises the indexed disk cache. This one uses three different regions for thre
@@ -52,17 +53,6 @@
     }
 
     /**
-     * Main method passes this test to the text test runner.
-     * <p>
-     * @param args
-     */
-    public static void main( String args[] )
-    {
-        String[] testCaseName = { HSQLDiskCacheConcurrentUnitTest.class.getName() };
-        junit.textui.TestRunner.main( testCaseName );
-    }
-
-    /**
      * A unit test suite for JUnit. Uses ActiveTestSuite to run multiple tests concurrently.
      * <p>
      * @return The test suite
@@ -126,7 +116,6 @@
         CacheAccess<String, String> jcs = JCS.getInstance( region );
 
         // Add items to cache
-
         for ( int i = 0; i <= items; i++ )
         {
             jcs.put( i + ":key", region + " data " + i );
@@ -135,7 +124,6 @@
 //        System.out.println( jcs.getStats() );
 
         // Test that all items are in cache
-
         for ( int i = 0; i <= items; i++ )
         {
             String value = jcs.get( i + ":key" );
@@ -159,14 +147,12 @@
         }
 
         // Remove all the items
-
         for ( int i = 0; i <= items; i++ )
         {
             jcs.remove( i + ":key" );
         }
 
         // Verify removal
-
         for ( int i = 0; i <= items; i++ )
         {
             assertNull( "Removed key should be null: " + i + ":key", jcs.get( i + ":key" ) );
diff --git a/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/jdbc/hsql/HSQLDiskCacheUnitTest.java b/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/jdbc/hsql/HSQLDiskCacheUnitTest.java
index d6c0294..58d7e77 100644
--- a/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/jdbc/hsql/HSQLDiskCacheUnitTest.java
+++ b/commons-jcs-core/src/test/java/org/apache/commons/jcs/auxiliary/disk/jdbc/hsql/HSQLDiskCacheUnitTest.java
@@ -1,5 +1,14 @@
 package org.apache.commons.jcs.auxiliary.disk.jdbc.hsql;
 
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.jcs.JCS;
+import org.apache.commons.jcs.access.CacheAccess;
+import org.apache.commons.jcs.access.exception.CacheException;
+import org.apache.commons.jcs.engine.behavior.ICacheElement;
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -20,18 +29,9 @@
  */
 
 import junit.framework.TestCase;
-import org.apache.commons.jcs.JCS;
-import org.apache.commons.jcs.access.CacheAccess;
-import org.apache.commons.jcs.access.exception.CacheException;
-import org.apache.commons.jcs.engine.behavior.ICacheElement;
-
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
 
 /**
- * Test which exercises the indexed disk cache. This one uses three different regions for thre
- * threads.
+ * Test which exercises the HSQL cache.
  */
 public class HSQLDiskCacheUnitTest
     extends TestCase
@@ -61,22 +61,15 @@
         CacheAccess<String, String> jcs = JCS.getInstance( region );
 
         // Add items to cache
-
         for ( int i = 0; i <= items; i++ )
         {
             jcs.put( i + ":key", region + " data " + i );
         }
 
-        //SleepUtil.sleepAtLeast( 1000 );
-
-//        System.out.println( jcs.getStats() );
-
         // Test that all items are in cache
-
         for ( int i = 0; i <= items; i++ )
         {
             String value = jcs.get( i + ":key" );
-
             assertEquals( "key = [" + i + ":key] value = [" + value + "]", region + " data " + i, value );
         }
 
@@ -95,16 +88,13 @@
             assertEquals( "value " + i + ":key", region + " data " + i, element.getVal() );
         }
 
-
         // Remove all the items
-
         for ( int i = 0; i <= items; i++ )
         {
             jcs.remove( i + ":key" );
         }
 
         // Verify removal
-
         for ( int i = 0; i <= items; i++ )
         {
             assertNull( "Removed key should be null: " + i + ":key", jcs.get( i + ":key" ) );
@@ -126,7 +116,6 @@
         int items = 20;
 
         // Add items to cache
-
         for ( int i = 0; i <= items; i++ )
         {
             jcs.put( i + ":key", region + " data " + i );
@@ -146,7 +135,6 @@
         for ( int i = 0; i <= items; i++ )
         {
             String value = jcs.get( i + ":key" );
-
             assertNull( "value should be null key = [" + i + ":key] value = [" + value + "]", value );
         }
     }
@@ -166,7 +154,6 @@
         int items = 20;
 
         // Add items to cache
-
         for ( int i = 0; i <= items; i++ )
         {
             jcs.put( i + ":key", region + " data " + i );
@@ -175,14 +162,11 @@
         // a db thread could be updating the disk when
         // Thread.sleep( 500 );
 
-//        System.out.println( jcs.getStats() );
-
         jcs.clear();
 
         for ( int i = 0; i <= items; i++ )
         {
             String value = jcs.get( i + ":key" );
-
             assertEquals( "key = [" + i + ":key] value = [" + value + "]", region + " data " + i, value );
         }
     }
diff --git a/commons-jcs-core/src/test/test-conf/TestHSQLDiskCache.ccf b/commons-jcs-core/src/test/test-conf/TestHSQLDiskCache.ccf
index 5134103..e3fe8b9 100644
--- a/commons-jcs-core/src/test/test-conf/TestHSQLDiskCache.ccf
+++ b/commons-jcs-core/src/test/test-conf/TestHSQLDiskCache.ccf
@@ -67,6 +67,7 @@
 jcs.auxiliary.HSQL_NORA.attributes.testBeforeInsert=false
 jcs.auxiliary.HSQL_NORA.attributes.maxTotal=15
 jcs.auxiliary.HSQL_NORA.attributes.allowRemoveAll=false
+jcs.auxiliary.HSQL_NORA.attributes.useDiskShrinker=false
 jcs.auxiliary.HSQL_NORA.attributes.MaxPurgatorySize=10000000
 jcs.auxiliary.HSQL_NORA.attributes.EventQueueType=POOLED
 jcs.auxiliary.HSQL_NORA.attributes.EventQueuePoolName=disk_cache_event_queue
diff --git a/commons-jcs-core/src/test/test-conf/TestHSQLDiskCacheConcurrent.ccf b/commons-jcs-core/src/test/test-conf/TestHSQLDiskCacheConcurrent.ccf
index 908de0f..8f2eb68 100644
--- a/commons-jcs-core/src/test/test-conf/TestHSQLDiskCacheConcurrent.ccf
+++ b/commons-jcs-core/src/test/test-conf/TestHSQLDiskCacheConcurrent.ccf
@@ -68,6 +68,7 @@
 jcs.auxiliary.HSQL_NORA.attributes.testBeforeInsert=false
 jcs.auxiliary.HSQL_NORA.attributes.maxTotal=15
 jcs.auxiliary.HSQL_NORA.attributes.allowRemoveAll=false
+jcs.auxiliary.HSQL_NORA.attributes.useDiskShrinker=false
 jcs.auxiliary.HSQL_NORA.attributes.MaxPurgatorySize=10000000
 jcs.auxiliary.HSQL_NORA.attributes.EventQueueType=POOLED
 jcs.auxiliary.HSQL_NORA.attributes.EventQueuePoolName=disk_cache_event_queue