I have a Java web application running in Tomcat that embeds an HSQLDB server database. I am attempting to encrypt this database.
The first time that I start Tomcat the database is created fine, the files appear encrypted and the application functions as expected. However when I shutdown Tomcat and restart, I get the following error:
5990 [main] DEBUG uk.co.my.db.HyperSqlDbServer - Starting HSQL server...
[Server@e79eb3]: [Thread[main,5,main]]: checkRunning(false) entered
[Server@e79eb3]: [Thread[main,5,main]]: checkRunning(false) exited
[Server@e79eb3]: [Thread[main,5,main]]: setDatabasePath(0,file:C:\path\to\my\db\dbname;crypt_key=6f841e23d0976a695e7bc7d122c1927d;crypt_type=AES)
[Server@e79eb3]: [Thread[main,5,main]]: checkRunning(false) entered
[Server@e79eb3]: [Thread[main,5,main]]: checkRunning(false) exited
[Server@e79eb3]: [Thread[main,5,main]]: setDatabaseName(0,dbname)
[Server@e79eb3]: [Thread[main,5,main]]: checkRunning(false) entered
[Server@e79eb3]: [Thread[main,5,main]]: checkRunning(false) exited
[Server@e79eb3]: Initiating startup sequence...
[Server@e79eb3]: Server socket opened successfully in 0 ms.
[Server@e79eb3]: [Thread[HSQLDB Server @e79eb3,5,main]]: Database [index=0, db=file:C:\path\to\my\db\dbname, alias=dbname] did not open: org.hsqldb.HsqlException: java.io.IOException: Not in GZIP format
[Server@e79eb3]: Startup sequence completed in 344 ms.
[Server@e79eb3]: 2015-11-03 10:51:32.137 HSQLDB server 2.2.4 is online on port 9001
[Server@e79eb3]: To close normally, connect and execute SHUTDOWN SQL
[Server@e79eb3]: From command line, use [Ctrl]+[C] to abort abruptly
The relevant portions of my startup and shutdown code are as follows:
/*
* (non-Javadoc)
* @see org.springframework.context.Lifecycle#start()
*/
public void start() {
if (server == null) {
logger.debug("Starting HSQL server...");
server = new Server();
// NB: explicitly setting path and name as it didn't work having them in properties file
server.setDatabasePath(0, properties.getProperty("server.database.0"));
server.setDatabaseName(0, properties.getProperty("server.dbname.0"));
try {
server.setProperties(properties);
server.start();
running = true;
} catch(Exception e) {
logger.error("Error starting HSQL server", e);
throw new ConfigurationException(e);
}
}
}
/*
* (non-Javadoc)
* @see org.springframework.context.Lifecycle#stop()
*/
public void stop() {
logger.debug("Stopping HSQL server...");
ShutdownDAO shutdown = context.getBean(ShutdownDAO.class);
if (server != null) {
shutdown.shutdownDatabase();
server.shutdown();
server.stop();
running = false;
}
}
The ShutdownDAO.shutdownDatabase() method performs the following:
public void shutdownDatabase(){
jdbcTemplate.execute("SHUTDOWN COMPACT");
}
The properties referred to in the start() method are set up as follows:
// NB: these first two properties only seem to work as part of the path and don't get picked up when in the properties file
internalDbProps.put("crypt_key", this.internalCryptKey);
internalDbProps.put("crypt_type", "AES");
internalDbProps.put("server.database.0", "file:C:\path\to\my\db\dbname;crypt_key=" + this.internalCryptKey + ";crypt_type=AES");
internalDbProps.put("server.dbname.0","dbname");
internalDbProps.put("server.remote_open","true");
internalDbProps.put("hsqldb.reconfig_logging","false");
internalDbProps.put("shutdown","true");
If I do not attempt to encrypt the database, all works fine.
The critical portion is the exception did not open: org.hsqldb.HsqlException: java.io.IOException: Not in GZIP format - this suggests to me that the database has not been shut down correctly. I have tried both SHUTDOWN and SHUTDOWN COMPACT when shutting down the database to see if this was causing the issue but to no avail.
Relevant exerpts from logs when shut down are as follows:
21515 [HSQLDB Connection @fbfa2] INFO hsqldb.db.HSQLDB50CD101BCF.ENGINE - Database closed
21906 [HSQLDB Connection @fbfa2] INFO hsqldb.db.HSQLDB50CD101BCF.ENGINE - Database closed
[Server@63f6ea]: Initiating shutdown sequence...
[Server@63f6ea]: Shutdown sequence completed in 0 ms.
[Server@63f6ea]: 2015-11-03 11:16:49.726 SHUTDOWN : System.exit() was not called
The folder which contains the database contains only the dbname.properties and dbname.script files after shutdown. The .properties file contains the following:
#HSQL Database Engine 2.2.4
#Tue Nov 03 11:16:49 GMT 2015
version=2.2.4
modified=no
The .script file appears to be encrypted.
When Tomcat is restarted however, the above error is encountered.
Please note that due to client constraints I am limited to Java 5 - so am using hsqldb-j5 2.2.4. If this is fixed in a future release I may not be in a position to upgrade.
EDIT - Java 5 information
As pointed out by fredt below, the Java 5 version is available from Maven with the following in pom.xml
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>2.3.3</version>
<classifier>jdk5</classifier>
</dependency>
Unfortunately the error still persists at J5 - but this may be of use to others in future.
EDIT - Additional information
Connections to the database are pooled using C3P0 - could this be making a difference to how the database shuts down perhaps?
The problem was caused by the encryption key being corrupted between restarts of the server by code elsewhere. The database was therefore being decrypted incorrectly and causing the GZIP format error encountered.