Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to check if an application already running in WinNT

0 views
Skip to first unread message

Hayward Lam

unread,
Apr 9, 1999, 3:00:00 AM4/9/99
to
Hi all,

There should be only one instance of our Java application running on
WinNT box.
Is it possible to do the check within our Java application (without JNI
involvement)?

Thanks.
Hayward

Kevin J. Grittner

unread,
Apr 9, 1999, 3:00:00 AM4/9/99
to
Hayward,

I can think of one way -- have the application open a TCP/IP
ServerSocket on some specific port number. If there's already an
application on the box with that port open, you should get an exception
that you can catch, and do whatever is appropriate for the duplicate
application.

-Kevin

Mark McMillan

unread,
Apr 9, 1999, 3:00:00 AM4/9/99
to
Can someone append a snipet of code that does this? I toyed with it for
quite a while before I gave up and wrote a 10 line C++ JNI program to do
it. I would really like to do it 100% Java but could not figure out all
the socket APIs.

Also, what is the probability of picking a port number that is *really*
in use by some other appliation (Java or otherwise)? Then your app
would mutually exclusive with the other. How big is the IP socket name
space?

-Mark

Eric Rizzo

unread,
Apr 9, 1999, 3:00:00 AM4/9/99
to Mark McMillan
Mark McMillan wrote:
>
> Can someone append a snipet of code that does this?

I think it's more common to use a file lock instead of a socket lock
(see below), but...
Look at java.net.ServerSocket. The constructor that takes a port number
is the one you want. That should bind to the port and lock out other
processes from the specific port. Make sure to call close() when the
app is done.

> Also, what is the probability of picking a port number that is *really*
> in use by some other appliation (Java or otherwise)? Then your app
> would mutually exclusive with the other.

This is a more interesting question. You can pass 0 in to the
ServerSocket constructor, and the OS will find an available port for
you. Then, get the port with getLocalPort() and write it to a file.
When your app starts up, it checks for the existence of that file. If
it doesn't exist, start-up proceeds. If it exists, read the port number
from it and try to create a new socket on it. If that fails, you know
the app is already running. If that succeeds, it means your app
died/exited without deleting the file.
That's a complex scheme, thus my preference of using a simple file lock
instead.
Also, I haven't done low-level socket programming since my C++/Solaris
days, but there can be problems with ports being freed (may take a
while) if their bound process dies ungracefully, which would give you
false positives about the app being running.

Hope this helps,
Eric

--
Eric Nicholas Rizzo
The Technical Resource Connection, Inc. Perot Systems
eric....@trcinc.com http://italy.eng.miami.edu/~erizzo
---------------------------------------------------------------
"Don't make me come down there!"
-God

Kevin J. Grittner

unread,
Apr 9, 1999, 3:00:00 AM4/9/99
to
Mark McMillan wrote:
>
> Can someone append a snipet of code that does this?

java.net.ServerSocket ss = new java.net.ServerSocket( APPSOCKET );

Be sure you do a ss.close() on application exit, or it may take a minute
for the socket to clear.

> Also, what is the probability of picking a port number that is *really*
> in use by some other appliation (Java or otherwise)? Then your app

> would mutually exclusive with the other. How big is the IP socket name
> space?

The range you can assign to APPSOCKET is 1 to 65535. You (or someone in
your organization) should be aware of the server socket numbers used by
services running on your machines. If you pick one near the top of the
range that is not currently in use by any software you're running, you
avoid having to write the port number to a disk file (as Eric Rizzo
suggested), with the unlikely possibility that you'll need to assign a
new number if you start running a new server product on a machine that
can be running your application. The server socket port numbers are a
different animal from the "normal" IP port numbers, so you don't need to
worry about a conflict with these.

Make sure you talk to whoever is responsible for managing IP in your
network about what server port numbers you're using for what.

-Kevin

P.S. I haven't actually used this technique for mutual exclusion --
intentionally, that is. But I've written server software, and am
familiar with what happens if I accidentally try to start a second
instance of the server.

Ivan Pastine

unread,
Apr 10, 1999, 3:00:00 AM4/10/99
to
Weird, I just yesterday I ran into a web page explainging this with
example code. I forget the adress but I saved a copy of it, pasted
below.

The author has a point, I think, about using file locking. What happens
when the application crashes (through no fault of our own, of course)
due to power failure etc? But socket listening method begs the question
about how to be sure you are listening at a free socket. If you are
writing for a particular server, no problem. But if you are distributing
generally this is a big issue.

Anybody have any other ideas?
Ivan


================
Preventing Multiple Instances of a Java Program from Running
Simultaneously

There is no Java-provided mechanism to ensure that only one instance of
a Java application is running at any one time. From the
operating system's perspective, when you run a Java application you're
simply running another application -- the fact that this
application happens to be a Java VM which will in turn run your Java
application is entirely irrelevant to the operating system. If you're
running two instances of the same Java application, you're simply
running two instances of the Java VM.

To ensure only one instance of your application is running at a time,
you must establish some communication mechanism whereby a
running instance of the application can inform other instances that they
should not run. When an instance of the application starts, it
first checks some condition that indicates whether or not it is okay to
proceed. If that condition is not met, the application should shut
itself down.

A seemingly simple way to do this is via the existence of a common file.
The existence of the file serves as a "flag" to indicate an
instance of the application is already running. The code here is pretty
simple:

import java.io.*;

public class OneInstance {
public static void main(String[] args) {
// Set up a "flag file" whose existence indicates the
application
// is already running.
File flagFile = new File("c:\\temp\\FlagFile");

try {
if(false == flagFile.createNewFile()) {
System.out.println("This program is already running...");
System.exit(1);
}
catch(IOException e) {
System.err.println("IOException: " + e);
System.exit(1);
}

System.out.println("This is the first instance of this
program...");

// Mark the "flag file" for automatic deletion when the VM
ends.
// But this only applies if the VM terminates normally.
flagFile.deleteOnExit();

// Do some useful work here...
}
}


Unfortunately, even though this program looks like it should work (and
it usually will), there are a couple problems with it:

1.If the VM terminates abnormally after the "flag file" has been
created, the "flag file" will not be deleted. When the application is
restarted it will find the "flag file" still exists from a previous
execution and will shut itself down.

2.If the "flag file" is deleted (either accidentally or
intentionally) while the first instance of the application is executing,
a second
instance of the application will begin executing. Because the
second instance of the application will successfully create its own
"flag file", it will assume it is the only instance in existence.

Now for a version that does work. The program shown below uses a
java.net.ServerSocket rather than files. When the
program starts, it tries to create a ServerSocket on a predefined port
(port 1942, in this example). Because only one
ServerSocket can listen on a given port at any one time, any attempt by
another application to listen on the same port will fail. The
program below assumes that When the creation of a ServerSocketfails, it
is because a previous instance of the application has
already created a ServerSocket listening on the same port.

import java.io.*;
import java.net.*;

public class OneInstance {
private static ServerSocket listenerSocket;

public static void main(String[] args) {
try {
listenerSocket = new ServerSocket(1942);
// At this point, no other socket may listen on port 1942.
}
catch(IOException e) {
System.err.println("There is probably another instance of\n"
+
"this application already running.\n" +
e);
System.exit(1);
}

// For this simple program, we simulate doing useful
// work by simply sleeping for 30 seconds. While we
// are sleeping, no other instance of this program will be
// able to execute.
System.out.println("Starting to sleep...");

try {
Thread.sleep(30000);
}
catch(InterruptedException e) {}

System.out.println("Waking up, program is about to end...");
}
}

Eric Rizzo

unread,
Apr 12, 1999, 3:00:00 AM4/12/99
to
Ivan Pastine wrote:
>
> The author has a point, I think, about using file locking. What happens
> when the application crashes (through no fault of our own, of course)
> due to power failure etc? But socket listening method begs the question
> about how to be sure you are listening at a free socket. If you are
> writing for a particular server, no problem. But if you are distributing
> generally this is a big issue.
>
> Anybody have any other ideas?

I always saw the problem of file locks lying around after a bad failure
to be easily resolved by manually deleting the file. You could include
a search for the file automatically at boot-time, if you operating
system will let you. I guess this could be reasonable or not depending
on your situation.

As for the socket problem mentioned here, the port number can be made
easily configurable through a properties file, Then if the one you
choose by default is already taken on a target machine, the user can
just edit the props file and change it.
There is still the issue about sockets not being freed immediately when
a process dies ungracefully. Any experiences on that in Java?

Rick Poleshuck

unread,
Apr 12, 1999, 3:00:00 AM4/12/99
to
In article <3711F118...@trcinc.com>,

Eric Rizzo <eric....@trcinc.com> wrote:
> There is still the issue about sockets not being freed immediately when
> a process dies ungracefully. Any experiences on that in Java?
>
> Eric
>

We have been in production with a small number of users using this solution
for a couple of months. No problems reported yet.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own

Kevin J. Grittner

unread,
Apr 12, 1999, 3:00:00 AM4/12/99
to
Eric Rizzo wrote:
>
> Ivan Pastine wrote:
> >
> > The author has a point, I think, about using file locking. What happens
> > when the application crashes (through no fault of our own, of course)
> > due to power failure etc? But socket listening method begs the question
> > about how to be sure you are listening at a free socket. If you are
> > writing for a particular server, no problem. But if you are distributing
> > generally this is a big issue.
> >
> > Anybody have any other ideas?
>
> I always saw the problem of file locks lying around after a bad failure
> to be easily resolved by manually deleting the file. You could include
> a search for the file automatically at boot-time, if you operating
> system will let you. I guess this could be reasonable or not depending
> on your situation.
>
> As for the socket problem mentioned here, the port number can be made
> easily configurable through a properties file, Then if the one you
> choose by default is already taken on a target machine, the user can
> just edit the props file and change it.
> There is still the issue about sockets not being freed immediately when
> a process dies ungracefully. Any experiences on that in Java?

A ServerSocket in an application that terminates abnormally has always
cleared pretty quickly for me in Java. Granted, this hasn't happened to
me very many times, so your milage may vary, but I think I've generally
been able to start up again with a few seconds.

I agree -- you would want to make the server port configurable,
especially for a program intended for general distribution.

If you prefer to write a file for your semaphore, how about having the
running program keep the file open? The file would be left there
permanently, but opened in a non-shared mode to aquire the semaphore.
I'm not sure what the best way is to get such a mode, or whether an
abnormally terminated program releases its hold on open files, but if
these two points could be resolved, this would work well. It seems more
foolproof than counting on the File.deleteOnExit method.

-Kevin

0 new messages