Hi,
I wonder if you know any way to check that a Java program can not run more than once. Let me explain, when the user runs a program for the second time, you get a message saying that it is already running the program.
Thank you very much.
Printable View
Hi,
I wonder if you know any way to check that a Java program can not run more than once. Let me explain, when the user runs a program for the second time, you get a message saying that it is already running the program.
Thank you very much.
When the program is run the first time, create or write to a file or property that the program will check when run the secound time?
Luck,
CJSL
Use a ServerSocket. It will only succeed once, a second attempt to bind the same socket will throw an exception (and no race condition).
Thank you for your quick reply.
I thought your solution but the problem is that if I create some sort of file properties, the route where you can save this file can change. Or maybe the user can modify the file directly.
Actually, Java has a Properties class which might be of help.
Properties (Java Platform SE 6)
Java: Properties
Luck,
CJSL
It's an easy solution that will work most of the time, but on that rare occasion where some other app (not a duplicate app) is using that socket, it will fail and leave no evidence as to why.
But you're on the right track. A system resource is needed. It seems like most apps use a lock file.
If your lock file doesn't exist, you create it. If you succeed in locking it, you are the singleton app and continue running. If you fail to lock it, you exit with a message.
File locks are automatically cleared by the OS when your process dies, so even if you crash somehow, it will be freed.
Not all file systems support filelocks, and then, if simply using a flag file without a lock, you have a race condition (same scenario with properties). Two apps check, and there is no file, so both attempt to create it (and are liable to both succeed), and you have two running apps. Yes, there could be something else running on the port, but as long as you are intelligent enough to pick an unlikely port, and make which port should be used configurable, I still consider that the best solution.
Edit: And even with locks, there is a problem. Locks only work as long as everything that might access the locked file "plays nice" (at least on most file systems). So, there is usually nothing to stop anything else from deleting the already locked lockfile and then starting the second app. Sockets are a bit harder to "force" free, and they also are automatically freed when the holding program quits (sometimes with a time wait delay, but then, normally, only when there was some actual traffic on the port, which, in this case, there won't be).
If you are "happy" with these failings, then by all means, stick with those methods, but the ServerSocket, IMHO, is the most reliable choice.
I tried this. Do you think is a good solution?
Code:try {
ServerSocket serverSocket = new ServerSocket(666);
myCode
} catch (IOException ioe) {
System.err.println("The program is running yet");
System.exit(1);
}
That is, essentially, how to do it, however, any port under 1024 is a bad choice, as the user running it would have to have adminstrator privilieges (i.e. root on unix), and most of those ports have predefined services. ports from 10,000 and higher are, normally, "random high ports" (i.e. any time the system needs to use a port where no port is predefined, it will take a port randomly from that range). But, since there usually is not that much simulteaneous traffic occurring, you shouldn't have any real problem using one of those, but you can't be sure of that. So, ports from 7000 to 9999 are usually good ports to use, but use a "strange" one, such as 9247, or something, that is not all that likely to be used by something else. Patterns such as 7777, or round numbers such as 7100, are more likely to be used than something like that.
Edit: I would also suggest explicitly binding to "localhost" (see the other ServerSocket constructors).
I done some changes...
What do you think?
serverSocket = new ServerSocket(8596,0,InetAddress.getByName("127.0.0 .1"));
Should be good.
I think we would have a problem if you have multiple users using the same pc (for example Terminal Server).
Can we ask why you want only one copy running? If you are trying to protect a system resource, can you not use that resource as your semaphore?
1.create some .txt or .dat file
2.Once the last line of the program is executed then update the created file in step 1 with todays date.
3.before execution it will check the file created in step 1 whether it is of todays date.
4.If it is todays date,then it will not execute again or else it will execute.So,the program execute only once per day.
Why not use a scheduler to just run it once per day? Task Scheduler on Windows or cron on linux
You could also change the privileges so, on linux for example, only cron can execute it.
No, that is what the ServerSocket is for. It can only be bound once, regardless of who is doing it, as long as the application is being executed from the same pc, of course, which it is if multiple users are accessing it over a terminal server, or any other remote access. Now, judging by the posts that have come after this last one of yours, do you want to avoid having it run mutliple times simulteneously, or only once per day. From the previous posts, I am, of course, assuming you want to avoid having multiple instances run in parallel, and are not wanting to restrict to once per day.