B4J Code Snippet B4J Single Instance checker irrespective of the Java version and packager used

This method works on my setup: Windows 10, B4J 9.10, OpenJDK 11. It works even if the jar or exe is copied or renamed.

B4X:
#AdditionalJar: sqlite-jdbc-3.36.0.1

Sub AppStart (Form1 As Form, Args() As String)

    MainForm = Form1
    MainForm.Show

    If ImAlreadyRunning(File.DirData("ThisProgram"), "lock.sqlite") Then
        fx.Msgbox(MainForm, "This program is already running", "No such luck")
        ExitApplication
        Return
    End If

'...

End Sub

Sub ImAlreadyRunning(dir As String, fileName As String) As Boolean

    If File.Exists(dir, fileName) Then
        Try
            ' Note: at least on Windows 10, no exception is thrown if the sqlite file is in use by
            ' another process. That's why the below 'Try' block with the SQL operations is there,
            ' and why it doesn't just open the database. A successful File.Delete is inconclusive.
            File.Delete(dir, fileName)
        Catch
            Return True
        End Try
    End If

    Try
        Dim sql1 As SQL
        sql1.InitializeSQLite(dir, fileName, True)
        sql1.BeginTransaction
        sql1.ExecNonQuery("CREATE TABLE IF NOT EXISTS TblLock(ColInt int)")
        sql1.ExecNonQuery("INSERT INTO TblLock (ColInt) VALUES (1)")
        sql1.TransactionSuccessful ' This will cause exception "java.sql.SQLException: database is locked" if another instance was already running
        ' IMPORTANT: do NOT close rs! (that's the whole point)
        Dim rs As ResultSet = sql1.ExecQuery("SELECT * FROM TblLock")
    Catch
        Return True
    End Try

    Return False

End Sub

Dependencies:
- Internal library: jSQL
- Additional jar: sqlite-jdbc-... : the latest one is 3.36.0.1 as per @Claudio Oliveira 's post: https://www.b4x.com/android/forum/threads/new-sqlite-jdbc-version-3-36-0-1-2021-06-30.132348/

EDIT: added the 'Note' comment.
 
Last edited:

Cableguy

Expert
Licensed User
Longtime User
Can you explain a use case for such code... some of us are just hobbyists with no formal background in software engineering
 

walt61

Active Member
Licensed User
Longtime User
I use it to make sure my 'client' for my home automation stuff is running just once on a PC (while it's ok to be running on multiple devices, but just one instance at a time on each device), as it uses/updates certain resources (files, databases) and would get confused if that's happening multiple times on the same PC. I could of course change my code to take multiple instances into account, but for this case that would be pointless.

Another example could be a program that shows itself in the system tray and you only want to see its icon there once.

Basically I'd say any program that requires exclusive access to certain resources could check if it's already running. Launch4J (the B4J packager I used with Java 8) has a 'single instance' option but as I moved to Java 11 and the integrated B4Jpackager11, I wanted that functionality too. A forum search showed that others had come up with solutions as well, but I could imagine situations where they wouldn't be bullet proof - I think mine is :)
 

Cableguy

Expert
Licensed User
Longtime User
I use it to make sure my 'client' for my home automation stuff is running just once on a PC (while it's ok to be running on multiple devices, but just one instance at a time on each device), as it uses/updates certain resources (files, databases) and would get confused if that's happening multiple times on the same PC. I could of course change my code to take multiple instances into account, but for this case that would be pointless.

Another example could be a program that shows itself in the system tray and you only want to see its icon there once.

Basically I'd say any program that requires exclusive access to certain resources could check if it's already running. Launch4J (the B4J packager I used with Java 8) has a 'single instance' option but as I moved to Java 11 and the integrated B4Jpackager11, I wanted that functionality too. A forum search showed that others had come up with solutions as well, but I could imagine situations where they wouldn't be bullet proof - I think mine is :)
Thank you for your explanation, very clear and I can now see the usefullness of this snippet
 
Top