Commit 35a3f4a1 authored by Andy Wilkinson's avatar Andy Wilkinson

Reinstate the use of shutdown hooks in the tests

Commit adf2c44b was an attempt to prevent HSQLDB from throwing an
exception when the JVM exits. This was achieved by disabling the
application context’s shutdown hook in the tests. This had the unwanted
side effect of causing tests’ application contexts not to be closed. The
reported symptom was that @Destroy methods were no longer being invoked.
We need a different solution to the problem.

The exception was:

Caused by: org.hsqldb.HsqlException: Database lock acquisition failure: attempt to connect while db opening /closing
    at org.hsqldb.error.Error.error(Unknown Source)
    at org.hsqldb.error.Error.error(Unknown Source)
    at org.hsqldb.error.Error.error(Unknown Source)
    at org.hsqldb.DatabaseManager.getDatabase(Unknown Source)
    at org.hsqldb.DatabaseManager.newSession(Unknown Source)
    ... 23 common frames omitted

I originally thought this was due to a race between the application
context’s shutdown hook and HSQLDB’s shutdown hook, however HSQLDB
doesn’t use a shutdown hook. I believe that the problem is due to 
an HSQLDB database being created with shutdown=true in its URL, similar
to the problem described here [1]. This will shut down the database when
the last connection to it is closed, however the shutdown will happen
asynchronously. If the JVM then runs the application context’s shutdown
hook, EmbeddedDatabaseFactory will attempt to connect to the database to
execute the SHUTDOWN command. This executes synchronously but will race
with the asynchronous shutdown that’s executing as a result of
shutdown=true in the JDBC url and the last connection to the database
being closed. 

This commit reinstates the use of application context shutdown hooks in
the tests, and updates the documentation to recommend that, if a user
manually configures the URL for their embedded database, they do so 
in such a way that the database doesn’t shutdown automatically, thereby
allowing the shutdown to be driven by application context close.

Closes gh-4208

[1] http://sourceforge.net/p/hsqldb/bugs/1400/
parent 1c46fd2a
...@@ -1526,6 +1526,13 @@ For example, typical POM dependencies would be: ...@@ -1526,6 +1526,13 @@ For example, typical POM dependencies would be:
</dependency> </dependency>
---- ----
TIP: If, for whatever reason, you do configure the connection URL for an embedded
database, care should be taken to ensure that the database’s automatic shutdown is
disabled. If you're using H2 you should use `DB_CLOSE_ON_EXIT=FALSE` to do so. If you're
using HSQLDB, you should ensure that `shutdown=true` is not used. Disabling the database's
automatic shutdown allows Spring Boot to control when the database is closed, thereby
ensuring that it happens once access to the database is no longer needed.
NOTE: You need a dependency on `spring-jdbc` for an embedded database to be NOTE: You need a dependency on `spring-jdbc` for an embedded database to be
auto-configured. In this example it's pulled in transitively via auto-configured. In this example it's pulled in transitively via
`spring-boot-starter-data-jpa`. `spring-boot-starter-data-jpa`.
......
...@@ -82,7 +82,6 @@ public class SpringApplicationContextLoader extends AbstractContextLoader { ...@@ -82,7 +82,6 @@ public class SpringApplicationContextLoader extends AbstractContextLoader {
throws Exception { throws Exception {
assertValidAnnotations(config.getTestClass()); assertValidAnnotations(config.getTestClass());
SpringApplication application = getSpringApplication(); SpringApplication application = getSpringApplication();
application.setRegisterShutdownHook(false);
application.setMainApplicationClass(config.getTestClass()); application.setMainApplicationClass(config.getTestClass());
application.setSources(getSources(config)); application.setSources(getSources(config));
ConfigurableEnvironment environment = new StandardEnvironment(); ConfigurableEnvironment environment = new StandardEnvironment();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment