The Artima Developer Community
Sponsored Link

Java Answers Forum
Ensuring single instance of app?

15 replies on 2 pages. Most recent reply: Aug 13, 2003 7:54 AM by John Gibby

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 15 replies on 2 pages [ 1 2 | » ]
Frank Sommers

Posts: 2642
Nickname: fsommers
Registered: Jan, 2002

Ensuring single instance of app? Posted: Aug 5, 2003 4:30 PM
Reply to this message Reply
Advertisement
In the case of a desktop Swing application, I'm trying to figure out how to ensure that only a single of the application runs at a time. Specifically, what I'd like is that when a user clicks on the application's icon, and if the application is already running (minimized), the app should just be restored to its regular window size, and second VM should not be started.

I can think of two things, but both are rather funky. The obvious solution is to have the app save a token file on disk. Then, when the user wants to start up the app again, if the file is present, a message would indicate that the app is already running. But that's very unfriendly, since I'd really like for the app to just restore its window. Plus, if the file is not removed when the app quits (e.g., if the app/machines crashes), then that causes extra problems.

The other option I thought of was to have the app listen on a socket. Since a socket port is a singleton per host (i.e., there is only one port 12345 per host), only one app can listen on that socket at a time. When the second app instance boots up, it would contact that port. If the port produces a reply, the second app would terminate, and the initial instance of the app would at the same time restore its window state. But that sounds like a lot of trouble for a relatively minor effect.

There's got to be a better way...


Greg Lehane

Posts: 33
Nickname: glehane
Registered: Jun, 2003

Re: Ensuring single instance of app? Posted: Aug 5, 2003 10:28 PM
Reply to this message Reply
hmmm.. seems like this should be simple. However it does sound like a job for JNI if you want the application itself to do the checking. Or at least a parsing a Runtime.exec() calls results to a task listing command.

You might want to consider doing the check in the script you use to run the process. If you're on windows, there may be a way to script something into your batch file. It should be easy on unix.

Just a thought,

=- Greg

Matt Gerrans

Posts: 1153
Nickname: matt
Registered: Feb, 2002

Re: Ensuring single instance of app? Posted: Aug 6, 2003 10:17 AM
Reply to this message Reply
On windows, it is a matter of using a mutex. This is a pretty common practice in Windows apps that want to be single instance and behave how you described:
1) On startup, before creating your main window, try to create the mutex, if it succeeds, proceed normally.
2) If it fails, do a FindWindow() on your own window class and send a custom Windows message (eg. WM_GUTEN_MORGEN) to the other instance and exit (some apps even do fancy stuff like pass command line parameters to the other instance -- you've probably seen this with MDI apps that open another child window in the existing instance, instead starting up a new instance of the app).
3) Handle the custom message by by restoring if iconized, coming to top, etc.

The problem with the file "mutex" is if your app crashes (not because of your code, of course, but because of some other app killing the system), the file can be left behind leaving you in a very annoying state for the user.

Frank, you asked about graphics configuration in Windows in another thread a while back -- I would suggest not trying to mess with the resolution settings programmatically. It is a complicated and dangerous business (you could easily set a resolution/freqency that results in a blank screen or worse). It would probably be simpler and safer to just pop up a some simple instructions and a button that can be clicked to pop up the display setting control panel (exec("control desk.cpl")). If you really, really must do it programmatically, let me know and I can give you more details (it will be all JNI, or you could simply create a stand-alone tool with C/C++ and Win32 API and call that).

David

Posts: 150
Nickname: archangel
Registered: Jul, 2003

Re: Ensuring single instance of app? Posted: Aug 8, 2003 4:28 AM
Reply to this message Reply
...or do something simpler....

Use the File classes createNewFile() and deleteOnExit() to create a temporary file on loading of your program. This file will automatically be removed on closure of your program.

You then just do a simple check to see that the file has not been created.

Vincent O'Sullivan

Posts: 724
Nickname: vincent
Registered: Nov, 2002

Re: Ensuring single instance of app? Posted: Aug 8, 2003 6:56 AM
Reply to this message Reply
> ...or do something simpler....
>
> Use the File classes createNewFile() and deleteOnExit() to
> create a temporary file on loading of your program. This
> file will automatically be removed on closure of your
> program.
>
> You then just do a simple check to see that the file has
> not been created.

...unless your program - or the operating system - crashes and the lock file isn't deleted.
...or you click a second time on the program icon before the lock file has been created.
...or the lock file or a super directory to it is deleted accidentally.

Right now, A colleage sitting next to me has implemented a system to prevent double log-ons by setting a user-logged-in flag on a DB when a user logs on or off. He now has a constant stream of calls requesting the flag be turned off because the app is telling them they're already logged in.

I warned him. I said it would happen but did he listen to me? Oh no...

V.

David

Posts: 150
Nickname: archangel
Registered: Jul, 2003

Re: Ensuring single instance of app? Posted: Aug 8, 2003 9:27 AM
Reply to this message Reply
> ...unless your program - or the operating system - crashes
> and the lock file isn't deleted.

If the O/S or JVM crashes you have bigger problems...

> ...or you click a second time on the program icon before
> the lock file has been created.

True.

> ...or the lock file or a super directory to it is deleted
> accidentally.

It'd take a super-user to delete an open file.

> Right now, A colleage sitting next to me has implemented a
> system to prevent double log-ons by setting a
> user-logged-in flag on a DB when a user logs on or off.
> He now has a constant stream of calls requesting the flag
> be turned off because the app is telling them they're
> already logged in.

That's why we have wonderful things called 'time-outs'

> I warned him. I said it would happen but did he listen to
> me? Oh no...

I do agree, it's generally more hassle than it's worth.

Frank Sommers

Posts: 2642
Nickname: fsommers
Registered: Jan, 2002

Re: Ensuring single instance of app? Posted: Aug 8, 2003 10:21 AM
Reply to this message Reply
> ...or do something simpler....
>
> Use the File classes createNewFile() and deleteOnExit() to
> create a temporary file on loading of your program. This
> file will automatically be removed on closure of your
> program.
>
> You then just do a simple check to see that the file has
> not been created.


Apart from the dangers of relying on a file that can either be deleted or just left there after a crash, I not only would like to prevent a user from logging in twice, but I'd also like to bring the existing instance of the app to the fore. I think that's a behaviour people expect on most OSs.

As for preventing double logins, one solution is to use JavaSpaces. At the initial login, the app could write an entry into the space. Since Javaspace entries have leases on them, the lease could be set to a few minutes. The app would renew the lease during the time of the user's session. If the client crashes, the worst case is that the stale entry lingers on in the space for a couple of more minutes. If the user then wants to log right back in, a warning can be displayed, asking the user if he wants to log in from the stale session. Answering yes would then remove the stale space entry. In essence, the space would then act as a global synchronization mechanism. While this solution may prevent double logins, it still doesn't help with the simple UI gesture of just restoring a minimized app's state, and bringing its window to the front.

Matt Gerrans

Posts: 1153
Nickname: matt
Registered: Feb, 2002

Re: Ensuring single instance of app? Posted: Aug 8, 2003 10:38 AM
Reply to this message Reply
> > ...unless your program - or the operating system -crashes
> > and the lock file isn't deleted.

> If the O/S or JVM crashes you have bigger problems...

I think having the file there is a bigger problem than a JVM crash, because that means the app can't start up again. There is a power switch (or plug!) on many computers these days and I'm sure there are still plenty of people who turn them off that way.

> That's why we have wonderful things called 'time-outs'

Then it's a lease, getting back to the Jini solution, right? Now it gets to be a pretty complicated solution to preventing an app from being multi-instance.

> I do agree, it's generally more hassle than it's worth.

I think there are fewer headaches using a mutex, provided the OS provides them (I'm not sure if all OSes do...).

One drawback of a virtual machine is that it often pretends that there is no real machine underneath. I guess the ideal would be if the OS would only run one instance of the JVM and run each app in its own sandbox inside it. I guess that would be like pre-installing a container in the OS...

Frank Sommers

Posts: 2642
Nickname: fsommers
Registered: Jan, 2002

Re: Ensuring single instance of app? Posted: Aug 8, 2003 10:46 AM
Reply to this message Reply
>
> The problem with the file "mutex" is if your app crashes
> (not because of your code, of course, but because of some
> other app killing the system), the file can be left behind
> leaving you in a very annoying state for the user.
>
> Frank, you asked about graphics configuration in Windows
> in another thread a while back -- I would suggest not
> trying to mess with the resolution settings
> programmatically. It is a complicated and dangerous
> business (you could easily set a resolution/freqency that
> results in a blank screen or worse). It would probably
> be simpler and safer to just pop up a some simple
> instructions and a button that can be clicked to pop up
> the display setting control panel (exec("control
> desk.cpl")). If you really, really must do it
> programmatically, let me know and I can give you more
> details (it will be all JNI, or you could simply create a
> stand-alone tool with C/C++ and Win32 API and call that).

Matt, thanks for your detailed reply. You convinced me that it's just not worth the effort and possible side effects. What's happenning is that several of our users went out and bought some new Dell PCs recently, and those machines come with a preset screen resolution of 800x600. So when they installed our app on those new machines, they found that the UI didn't fit on the screen. This caused a tech support situation for us, as our users had no idea what screen resolution was, let alone how to change it. Now I'm just going to have the app display a detailed message (perhaps even offering the option to print that message out) about changing the screen res.

As for the single instance of an app, this is something that should be easy. That it's not, is a symptom of a much bigger problem with Java on desktop in general. I guess that's something to blog about...

John Gibby

Posts: 2
Nickname: gadgetman
Registered: Jun, 2003

Re: Ensuring single instance of app? Posted: Aug 8, 2003 11:42 AM
Reply to this message Reply
Up front here I want to admit that I am a newbie Java programmer and make no claims to being an expert.

That said, couldn't this be solved by making it a singleton?

Matt Gerrans

Posts: 1153
Nickname: matt
Registered: Feb, 2002

Re: Ensuring single instance of app? Posted: Aug 8, 2003 12:22 PM
Reply to this message Reply
> Up front here I want to admit that I am a newbie Java
> programmer and make no claims to being an expert.
>
> That said, couldn't this be solved by making it a
> singleton?

Nope. A singleton would be single-instance in on each JVM, not on the machine (or the OS, as it were).

Usually, when you launch an app, a whole new JVM process is created to host it. (If you are on Windows, look at the Task Manager after running more than one java app and you'll see that there are several instances of java, on Linux/Unix/OS X look at ps).

This is the problem that Frank is thinking about when he suggests a blog on the topic. It is also what I was implying with the container comment above. If you could sort of integrate the JVM into the OS, so that the OS would pass requests to run class files off to the already-running JVM, instead of launching a new JVM, then that would solve the problem.

Frank, on the resolution thing, you can also provide the button to launch "control desk.cpl", which adds a little convenience and simplicity for the users. Even better than that, you can launch straight to the "Settings" tab, which has the resolution settings, by executing "rundll32 shell32.dll,Control_RunDLL desk.cpl,@0,4".

(I've not tried this from Java with Runtime.exec(). I don't remember whether it is necessary to fully-qualify the target program name. If so, replace rundll32 with "c:\\windows\\system32\\rundll32.exe"; of course, you should get the Windows system directory from the OS (API call), or at least use the windir environment variable and then add the "\\system32" part to it.)

Vincent O'Sullivan

Posts: 724
Nickname: vincent
Registered: Nov, 2002

Re: Ensuring single instance of app? Posted: Aug 10, 2003 11:57 AM
Reply to this message Reply
> > Right now, A colleage sitting next to me has implemented
> a
> > system to prevent double log-ons by setting a
> > user-logged-in flag on a DB when a user logs on or off.
> > He now has a constant stream of calls requesting the
> flag
> > be turned off because the app is telling them they're
> > already logged in.
>
> > I warned him. I said it would happen but did he listen
> to
> > me? Oh no...

After his experiences with the users on Friday, he's going to remove this 'feature' on Monday...

Matt Gerrans

Posts: 1153
Nickname: matt
Registered: Feb, 2002

Re: Ensuring single instance of app? Posted: Aug 10, 2003 8:02 PM
Reply to this message Reply
And maybe he read your post. ;-)

E Figueroa

Posts: 3
Nickname: ef
Registered: Aug, 2003

Re: Ensuring single instance of app? Posted: Aug 11, 2003 11:57 AM
Reply to this message Reply
Hi!
I'm a newbie here. But I found a solution by using the Mutex method. check this link:
http://www.codeguru.com/misc/single_instance_app.shtml

Matt Gerrans

Posts: 1153
Nickname: matt
Registered: Feb, 2002

Re: Ensuring single instance of app? Posted: Aug 11, 2003 6:23 PM
Reply to this message Reply
The solutions outlined on that page use MFC, which in this case provides little value for its bloat, as it offers no more simplicity than the underlying API.

I think for a Java solution, I'd avoid MFC. Instead, do it with the API: just wrap a couple API calls (CreateMutex(), FindWindow(), etc.) into a little JNI class that does the trick.

Flat View: This topic has 15 replies on 2 pages [ 1  2 | » ]
Topic: Java2 applets without the entire plugin Previous Topic   Next Topic Topic: accessing files

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use