I am in the uncomfortable situation where some tests work locally, but cause an exception once pushed to the repository and the build by Bamboo.
The error that occurs on Bamboo is as follows:
java.sql.SQLException: The database has been closed
It occurs here, in the line conn = DriverManager.getConnection(url):
public RequirementRepository(String folder) throws SQLException, DatabaseNotConnectedException {
new File(folder).mkdirs();
String url = "jdbc:sqlite:" + folder + "/requirement.db";
// create a connection to the database
conn = DriverManager.getConnection(url);
try (Statement statement = conn.createStatement()) {
[Very long SQL statement]
}
}
Interestingly, this does not fail always, but only sometimes.
I've already checked the URL in both succeeding and failing cases, and it is the same in both cases:
jdbc:sqlite:Test_Database/requirement.db
Any ideas what could cause or affect this, and why it only happens on Bamboo and not on my local machine? Even if I delete the database from my local machine so it has to be newly created, I can't replicate the error locally.
EDIT:
Here's the stack trace up to the point where it enters local code:
java.sql.SQLException: java.sql.SQLException: The database has been closed
java.sql.SQLException: The database has been closed
at org.sqlite.core.NativeDB.throwex(NativeDB.java:478)
at org.sqlite.core.NativeDB.errmsg_utf8(Native Method)
at org.sqlite.core.NativeDB.errmsg(NativeDB.java:144)
at org.sqlite.core.DB.newSQLException(DB.java:953)
at org.sqlite.core.DB.throwex(DB.java:918)
at org.sqlite.core.NativeDB._open_utf8(Native Method)
at org.sqlite.core.NativeDB._open(NativeDB.java:78)
at org.sqlite.core.DB.open(DB.java:195)
at org.sqlite.SQLiteConnection.open(SQLiteConnection.java:243)
at org.sqlite.SQLiteConnection.<init>(SQLiteConnection.java:61)
at org.sqlite.jdbc3.JDBC3Connection.<init>(JDBC3Connection.java:28)
at org.sqlite.jdbc4.JDBC4Connection.<init>(JDBC4Connection.java:21)
at org.sqlite.JDBC.createConnection(JDBC.java:116)
at org.sqlite.JDBC.connect(JDBC.java:90)
at java.sql.DriverManager.getConnection(DriverManager.java:664)
at java.sql.DriverManager.getConnection(DriverManager.java:270)
at dom_requirement.model.RequirementRepository.<init>(RequirementRepository.java:225)
Line 225 is:
conn = DriverManager.getConnection(url);
EDIT 2:
This notably also appears when the connection is being set like this:
public WorkspaceManager(String folder) throws SQLException {
new File(folder).mkdirs();
databaseConnectionUrl = "jdbc:sqlite:" + folder + "/workspace.db";
// create a connection to the database
try(Connection conn = DriverManager.getConnection(databaseConnectionUrl)){
try (Statement statement = conn.createStatement()) {
[Very long SQL statement]
}
}
}
In that case, the line causing the error is:
try(Connection conn = DriverManager.getConnection(databaseConnectionUrl)){
The stacktrace itself remains unchanged.
EDIT 3:
I now found a way to make it work, although that particular solution seems more like a workaround around a glitch than a proper solution, so I am still interested in hearing about ideas what might be the actual cause and how to fix it.
As mentioned above, the error appears only on tests on Bamboo. It's a total of 134 tests spread across 14 classes, all of which inherit from a RequirementControllerTest abstract class.
In the version where it fails on Bamboo, the SQL Connection is created in a @BeforeEach method in the RequirementControllerTest, so a fresh connection is created for each of the 134 tests.
We managed to get it to pass by switching this @BeforeEach method to a @BeforeAll method, so now the SQL Connection is only created 14 times instead of 134, and interestingly this works on Bamboo.
So the thing I wonder now is, how can this work if it's only done 14 times, but not if it's done 134 times? And why does it only happen on Bamboo?