I found that despite using the Singleton pattern for the database (=restricting access to only one DB file per JVM), java (SDK) decides to start a separate JVM for each application launch anyway. (Also refer to WikiPedia Singleton Pattern Java for a reference to this situation.
This really makes the Singleton pattnern not quite work as singular as anticipated. The "customer" can still open multiple instances of the database implementation per file. Those instances can then potentially corrupt each other since locking is not coordinated between the instances.
Anyone came across this issue?
If the application is aware that several instances of it can be running, then it's not hard to guard against this problem. A common way to prevent this is for the application to open a ServerSocket on a particular port. This will only succeed once, all app instances opened afterwards will get an exception, and should then quit.
So as you suggest, Singleton, static reference etc. is then superflous work when trying to guard against accidental/intentional access concurrency on the same file (e.g. RMI server running on file, then standalone client being opened on same file, resulting in data corruption risk due to duplicate instance of lock object sets).
You may assume that at any moment, at most one program is accessing the database file; therefore your locking system only needs to be concerned with multiple concurrent clients of your server.
a multi-datafile acces scenario can be assumed as non-existent.
[ UD: replaced CODE tags with QUOTE tags to preserve page layout ]
[ October 13, 2007: Message edited by: Ulf Dittmer ]
Much of this has to do with classloaders, and how classloaders load various Java classes. A singleton packaged and placed on various places on the classpath will potentially result in many instances of the singleton running.
Here's a good tutorial on classloaders if you're interested in learning more:
Classloading Demystified: Understanding J2EE JVM Classloaders at Runtime
Originally posted by Ulf Dittmer:
A common way to prevent this is for the application to open a ServerSocket on a particular port. This will only succeed once, all app instances opened afterwards will get an exception, and should then quit.
Another set of ideas to ensure application singularity per machine: Application Singularity