Skip to content

Potential endless loop in applications that open a non-existing database file #1260

@hofmandl1

Description

@hofmandl1

Describe the bug

The open function

private static DB open(String url, String origFileName, Properties props) throws SQLException {
has the (undocumented?) side-effect of temporarily creating a 0-bytes file when trying to open a non-existing database which seems to be an in-Java location-writeability test done before handing over control to native code.

The 0-bytes file is immediately deleted after creation, which thus may seem innocent, however our application sometimes tries to open non-existing sqlite database files (our application is working with multiple database files at once, that can be registered and deregistered and manual deletion of database files is something we support).

That attempt to open a non-existing database file then temporarily creates the database-file (with 0 bytes) leading to a filesystem level file-creation-event which our application also reacts to and which leads to another attempt of opening the database-file. As the database-file has already been deleted we have another attempt to open a non-existing database file and thus an endless loop or at least a long sequence of open attempts (the loop eventually breaks, if the open attempt happens before file-deletion).

Of course, there is a way to workaround this problem on application level, e.g. doing an existance check before attempting to open the database, however IMHO that should not be necessary as it
a) is bad practice because it is racy and
b) requires an additional filesystem access

Note, that our application also explicitly resets SQLiteOpenMode.CREATE because it is not supposed to create the databases it is working with on its own.

To Reproduce
A reproducer would involve filesystem watching and probably be highly scheduling-dependent, so I hope my explanation above is sufficient.

Expected behavior
It should be possible to just try to open the file and from the caught exception determine that the problem was a non-existing file without any side-effects like a temporarily created file.

Logs
N/A

Environment (please complete the following information):
I think we were observing this problem first (and maybe only) on windows, but it should be system-independent, and probably also depends on the OS scheduling.

Additional context
Our solution since a couple of years is to patch the open-function and simply remove the whole logic in the else-branch that creates the empty file
replacing it by simply doing fileName = new File(fileName).getAbsolutePath();
which is working flawlessly for us, since we've been building sqlite-jdbc ourselves for a couple of other reasons.
However, we would very much like to not build sqlite-jdbc ourselves anymore, hence this report.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions